Python中函数的默认参数问题

不羁的心 提交于 2020-04-04 08:43:44

前几天,运营反馈了一个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 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!