有时,默认参数为空列表似乎很自然。然而,Python在这些情况下会产生意想不到的行为。
例如,我有一个函数:
def my_func(working_list=[]):
working_list.append("a")
print(working_list)
第一次调用它时,默认值将工作,但之后的调用将更新现有列表(每次调用一个“a”)并打印更新后的版本。
那么,python的方法是什么来获得我想要的行为(每次调用都有一个新的列表)?
有时,默认参数为空列表似乎很自然。然而,Python在这些情况下会产生意想不到的行为。
例如,我有一个函数:
def my_func(working_list=[]):
working_list.append("a")
print(working_list)
第一次调用它时,默认值将工作,但之后的调用将更新现有列表(每次调用一个“a”)并打印更新后的版本。
那么,python的方法是什么来获得我想要的行为(每次调用都有一个新的列表)?
当前回答
在这种情况下,这并不重要,但你可以使用对象标识来测试None:
if working_list is None: working_list = []
你也可以利用python中布尔运算符or的定义:
working_list = working_list or []
但是,如果调用者给你一个空列表(算作false)作为working_list,并期望你的函数修改他给它的列表,这将出乎意料。
其他回答
def my_func(working_list=None):
if working_list is None:
working_list = []
# alternative:
# working_list = [] if working_list is None else working_list
working_list.append("a")
print(working_list)
文档说你应该使用None作为默认值,并在函数体中显式地测试它。
已经提供了正确的答案。我只是想给出另一种语法来写你想做的事情,当你想创建一个默认空列表的类时,我发现它更漂亮:
class Node(object):
def __init__(self, _id, val, parents=None, children=None):
self.id = _id
self.val = val
self.parents = parents if parents is not None else []
self.children = children if children is not None else []
这段代码使用了if else操作符语法。我特别喜欢它,因为它是一个简洁的小单行,没有冒号等,读起来几乎像一个正常的英语句子。:)
在你的情况下,你可以写作
def myFunc(working_list=None):
working_list = [] if working_list is None else working_list
working_list.append("a")
print working_list
引用自https://docs.python.org/3/reference/compound_stmts.html#function-definitions
Default parameter values are evaluated from left to right when the function definition is executed. This means that the expression is evaluated once, when the function is defined, and that the same “pre-computed” value is used for each call. 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. This is generally not what was intended. A way around this is to use None as the default, and explicitly test for it in the body of the function, e.g.:
def whats_on_the_telly(penguin=None):
if penguin is None:
penguin = []
penguin.append("property of the zoo")
return penguin
在这种情况下,这并不重要,但你可以使用对象标识来测试None:
if working_list is None: working_list = []
你也可以利用python中布尔运算符or的定义:
working_list = working_list or []
但是,如果调用者给你一个空列表(算作false)作为working_list,并期望你的函数修改他给它的列表,这将出乎意料。
其他答案已经提供了要求的直接解决方案,然而,由于这是Python程序员新手的一个非常常见的陷阱,因此值得添加对Python为什么会这样做的解释,这在可变默认参数下的Python漫游指南中得到了很好的总结:
Python的默认实参在定义函数时只计算一次,而不是每次调用函数时都计算(就像Ruby中那样)。这意味着如果你使用一个可变的默认参数并改变了它,你将在以后所有对函数的调用中也改变了这个对象。