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 
  • 相关阅读:
    如何从零开始开发一款嵌入式产品(20年的嵌入式经验分享学习)如何从零开始开发一款嵌入式产品(20年的嵌入式经验分享学习)
    shell命令【ulimit】
    ARM开发经典学习网站推荐
    [转]链表逆序
    [转]Rhythmbox中文乱码解决办法
    vi/vim 查找替换使用方法
    [转]程序员的十个层次 你属于哪一层?
    如何在程序中删除一个文件
    C/C++编译器错误代码大全
    R制作eset 的简单步骤
  • 原文地址:https://www.cnblogs.com/ruizhang3/p/6720879.html
Copyright © 2011-2022 走看看