【问题标题】:default arguments in Python [duplicate]Python中的默认参数[重复]
【发布时间】:2013-08-12 14:30:23
【问题描述】:

我对 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 实例。为什么所有实例都更改了?

【问题讨论】:

  • 是的,可能重复...

标签: python arguments default-arguments


【解决方案1】:

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

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

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 as default argument

【讨论】:

  • Python 绝对不会检查参数是否可变,如果是则通过引用传递。我希望人们不要在其他很好的答案中重复这一点。
  • @Wooble 不确定您的意思。我只是说可变对象是通过引用传递的。
  • 他们不是。 Python 不会通过引用传递。我建议阅读stackoverflow.com/a/986145/110707
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多