有时,默认参数为空列表似乎很自然。然而,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的方法是什么来获得我想要的行为(每次调用都有一个新的列表)?
当前回答
也许最简单的事情就是在脚本中创建列表或元组的副本。这样就避免了检查的需要。例如,
def my_funct(params, lst = []):
liste = lst.copy()
. .
其他回答
已经提供了正确的答案。我只是想给出另一种语法来写你想做的事情,当你想创建一个默认空列表的类时,我发现它更漂亮:
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
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作为默认值,并在函数体中显式地测试它。
在这种情况下,这并不重要,但你可以使用对象标识来测试None:
if working_list is None: working_list = []
你也可以利用python中布尔运算符or的定义:
working_list = working_list or []
但是,如果调用者给你一个空列表(算作false)作为working_list,并期望你的函数修改他给它的列表,这将出乎意料。
我可能跑题了,但请记住,如果你只是想传递一个可变数量的参数,python的方法是传递一个元组*args或一个字典**kargs。这些是可选的,比语法myFunc([1,2,3])更好。
如果你想传递一个元组:
def myFunc(arg1, *args):
print args
w = []
w += args
print w
>>>myFunc(1, 2, 3, 4, 5, 6, 7)
(2, 3, 4, 5, 6, 7)
[2, 3, 4, 5, 6, 7]
如果你想传递一个字典:
def myFunc(arg1, **kargs):
print kargs
>>>myFunc(1, option1=2, option2=3)
{'option2' : 2, 'option1' : 3}
也许最简单的事情就是在脚本中创建列表或元组的副本。这样就避免了检查的需要。例如,
def my_funct(params, lst = []):
liste = lst.copy()
. .