Python全局类属性

时间:2014-02-08 02:53:35

标签: python

我无法理解这是如何运作的。为什么Node的实例b如下面的代码所示知道wordlist?

class Node():
def __init__(self,wordList=[]):
    self.wordList = wordList

a = Node()
b = Node()

a.wordList.append("hahaha!")
print b.wordList
  
    

哈哈哈!

  

3 个答案:

答案 0 :(得分:3)

这是Python中常见的错误,直到你得到它的工作方式,并且 他们学会直觉地避免这种情况。

问题是__init__方法的默认参数 wordlist是由[ ]表示的空列表,只创建一次, 解析类体时。

之后,每次调用__init__方法(自动生成) 在对象实例化)传递相同的对象 - 单个空列表 - 作为函数的参数。因此,在上面的例子中,所有的实例 Node将指向相同的列表 - 这是您检测到的问题。

避免问题的正确模式是这样的:

class Node(object):
def __init__(self,wordList=None):
    if wordlist is None: wordlist = [] 
    self.wordList = wordList

这样,每次__init__调用都会创建一个新的空ist。

答案 1 :(得分:2)

在python中,默认参数与函数一起保存,在评估函数定义时会对它们进行一次求值,因为该类的所有实例只使用一个方法,因此该方法只有一个wordList默认值实例,所以它们就像C中的静态变量一样,这就是为什么你永远不应该有可变的默认参数,阅读本文以获取更多细节http://effbot.org/zone/default-values.htm

答案 2 :(得分:0)

这可能会让它更清晰:

class Node():
    def __init__(self,wordList=[]):
        self.wordList = wordList

a = Node()
b = Node()

print(id(a.wordList))
print(id(b.wordList))

会产生类似

的内容
41474968
41474968

...换句话说,a.wordList和b.wordList都引用相同的列表