Python中的默认参数

Python中的默认参数,python,arguments,default-arguments,Python,Arguments,Default Arguments,我对Python中的默认参数感到困惑。这是我的代码: #!/usr/bin/env python import sys class Node(object): def __init__(self, ID=str(), items=[]): self.ID = ID self.items = items if __name__ == '__main__': a = Node('1') b = Node('2') b.

我对Python中的默认参数感到困惑。这是我的代码:

#!/usr/bin/env python
import sys 
class Node(object):
     def __init__(self, ID=str(), items=[]):
         self.ID = ID
         self.items = items

 if __name__ == '__main__':
     a = Node('1')
     b = Node('2')
     b.items.append('sth.')
     c = Node('3')
     print a.items
     print b.items
     print c.items

The output is:
['sth.']
['sth.']
['sth.']

我只是更改了b实例。为什么所有实例都被更改?

这是一个参考案例。由于列表
是可变的(可以通过内部方法直接更改),因此您在任何函数中对它所做的任何更改都会反映在对它的所有引用中

例如,如果您有以下代码:

def f(x):
    x.append(5)

a = [1, 2, 3]
f(a)
# a is now [1, 2, 3, 4], even in the global scope
这是因为
a
是一个可变列表,因此它是通过引用传递的

因此,当您使用
items=[]
时,您是在程序启动时创建一个空白列表,而不是每次创建新实例时。相反,每个实例引用相同的列表,该列表是在“声明”类时创建的。因此,由于每个实例都引用相同的列表,因此它们都会发生更改

要解决此问题,请将构造函数更改为:

def __init__(self, ID=str(), items=None): # you can also use '' instead of str()
    if not items: items = []
    # everything else
有几个好的链接可以更好地/以不同的方式解释这一点:


还有很多其他类似的问题,只需搜索
[python]None作为默认参数

这是一个参考案例。由于列表
是可变的(可以通过内部方法直接更改),因此您在任何函数中对它所做的任何更改都会反映在对它的所有引用中

例如,如果您有以下代码:

def f(x):
    x.append(5)

a = [1, 2, 3]
f(a)
# a is now [1, 2, 3, 4], even in the global scope
这是因为
a
是一个可变列表,因此它是通过引用传递的

因此,当您使用
items=[]
时,您是在程序启动时创建一个空白列表,而不是每次创建新实例时。相反,每个实例引用相同的列表,该列表是在“声明”类时创建的。因此,由于每个实例都引用相同的列表,因此它们都会发生更改

要解决此问题,请将构造函数更改为:

def __init__(self, ID=str(), items=None): # you can also use '' instead of str()
    if not items: items = []
    # everything else
有几个好的链接可以更好地/以不同的方式解释这一点:


还有很多其他类似的问题,只需搜索
[python]None作为默认参数

是的,可能重复…是的,可能重复…python绝对不会检查参数是否可变,如果可变则通过引用传递。我希望人们不要在其他好的回答中重复这一点。@Wooble不知道你的意思。我只是说可变对象是通过引用传递的,它们不是。Python不做按引用传递。我建议阅读Python绝对不会检查参数是否可变,如果可变,则通过引用传递。我希望人们不要在其他好的回答中重复这一点。@Wooble不知道你的意思。我只是说可变对象是通过引用传递的,它们不是。Python不做按引用传递。我建议阅读