zoukankan      html  css  js  c++  java
  • Python中函数的默认参数问题

    前几天,运营反馈了一个BUG,某些数据在写入数据库后,其时间字段出现异常,与当前时间相差较多。

    由于代码是不是我写的,所以开始一遍阅读代码一遍排查问题。

    在主流程中,仅仅发现了一个对时间赋值的语句,并且赋值使用的是data.CreateTime=int(time.time())这样的形式,应该没有问题。

    在别的地方没有找到对该字段赋值的操作,于是想看看这个类是不是自身有什么方法会修改时间字段。

    最终在类初始化函数中找到了这样的内容

    1 class Data():
    2     def __init__(a, b=None, CreateTime=int(time.time())):
    3         self.a = a
    4         self.b = b
    5         self.CreateTime = CreatTime

    问题就出现在这里,在Python官方文档中有这么一句话:

    Default parameter values are always evaluated when, and only when, the “def” statement they belong to is executed.

    https://docs.python.org/3/reference/compound_stmts.html

    意思是,默认参数始终在且仅在函数定义时赋值一次,所以上面的代码造成的问题是,如果该类在实例化时没有传入Creatime参数,则其CreateTime参数会默认为程序启动的时间。

    另外,如果参数默认值是可变对象,那么会出现另外一个问题,如果函数修改了这个对象,那么默认值也会被修改。

    This is especially important to understand when a default parameter is a mutable object, such as a list or a dictionary: if the function modifies the object (e.g. by appending an item to a list), the default value is in effect modified.

    如果写出了如下代码:

    def f(a, L=[]):
        L.append(a)
        return L
    
    print f(1)
    print f(2)
    print f(3)

    则其输出为:

    [1]
    [1, 2]
    [1, 2, 3]

    那么如何解决这个问题呢?

    一般情况下,推荐的解决方式是,使用None作为参数的默认值,然后进行判断,如果发现参数为None,则重新对其进行赋值。

    对于最开始的例子,解决之后的代码如下:

    1  class Data():
    2      def __init__(a, b=None, CreateTime=None):
    3          self.a = a
    4          self.b = b
    5          self.CreateTime = int(time.time()) if CreateTime is None else CreateTime 
  • 相关阅读:
    面向对象和面向过程的区别
    k-means算法
    win10系统下安装mysql
    python并发编程之多进程
    操作系统的概念
    前端基础之html
    聚类分析
    决策树
    Mysql
    SQL练习题
  • 原文地址:https://www.cnblogs.com/ruizhang3/p/6720879.html
Copyright © 2011-2022 走看看