有时,默认参数为空列表似乎很自然。然而,Python在这些情况下会产生意想不到的行为。

例如,我有一个函数:

def my_func(working_list=[]):
    working_list.append("a")
    print(working_list)

第一次调用它时,默认值将工作,但之后的调用将更新现有列表(每次调用一个“a”)并打印更新后的版本。

那么,python的方法是什么来获得我想要的行为(每次调用都有一个新的列表)?


当前回答

已经提供了正确的答案。我只是想给出另一种语法来写你想做的事情,当你想创建一个默认空列表的类时,我发现它更漂亮:

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

其他回答

我可能跑题了,但请记住,如果你只是想传递一个可变数量的参数,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()
         . . 

我参加了UCSC的编程扩展课程Python

这是真的:def Fn(data = []):

A)是一个好主意,这样你的数据列表在每次调用时都是空的。 B)是一个好主意,这样所有不提供任何参数的函数调用都将获得空列表作为数据。 C)是一个合理的想法,只要你的数据是一个字符串列表。 D)是一个坏主意,因为默认的[]会积累数据,并且默认的[]会随着后续的调用而改变。

答:

D)是一个坏主意,因为默认的[]会积累数据,并且默认的[]会随着后续的调用而改变。

引用自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
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作为默认值,并在函数体中显式地测试它。