2016-04-28 110 views
2

我正在从过去3个月的Python 2.7工作,今天注意到这一点后,我真的很惊讶。python字典,列表有相同的实例所有类

对于代码

class Example: 
    children = {} 

instance1 = Example() 
instance1.children['instance1_child1'] = 'Instance 1 child 1' 

instance2 = Example() 
instance2.children['instance2_child1'] = 'Instance 2 child 1' 
for key, value in instance2.children.items(): 
    print key + ' -> ' + value 

下面的代码片段为什么输出是

instance1_child1 -> Instance 1 child 1 
instance2_child1 -> Instance 2 child 1 

好像只有一个字典()的所有我创建的对象的实例。我也使用list []进行了检查,他们的行为也是一样的。

我无法理解python的这种行为,它背后的逻辑是什么。这是某种设计缺陷还是我做错了什么,应该退出编程?

+1

是它是'Example'类的一个静态成员。如果你想让它成为每个实例成员,那么它需要被附加到self,即在'__init__'方法中将其定义为'self.children'。 –

+1

您已使用类变量。你必须为你的情况使用实例变量。在这里阅读:[类和实例变量](https://docs.python.org/2/tutorial/classes.html#class-and-instance-variables) – qvpham

+0

只是为了进一步复杂化,如果你插入了这个句子在你的代码中:'Example.children ['bar'] ='foo''那么你会得到这个额外的输出:'bar - > foo' – Tonechas

回答

7

通过创建一个成员函数的上下文之外这些变量,你已经在不知不觉中创造了一个类变量

类变量可以被每个类实例访问,并且可以直接从类本身访问而不需要实例化。

Example.children == Example().children 
>>> True 

认为等同于在一个类中定义的全局变量,并且您有答案。


为了解决这个问题,只要把它们的__init__范围内。

class Example(object): 

    def __init__(self): 
     self.children = {} 

现在children被绑定到类实例,而不是类本身。这是self的威力。

+0

将有助于添加一个代码的例子,这将正确创建实例变量 –

+1

@JulienSpronck我在这样做的过程中,当你评论:) –

+0

好!希望我能第二次upvote它:-) –

1

您已将children定义为类变量而不是实例变量。如果您将其更改为实例变量,而不是将表现为你所期望的:

class Example: 
    def __init__(self): 
     self.children = {} 

instance1 = Example() 
instance1.children['instance1_child1'] = 'Instance 1 child 1' 

instance2 = Example() 
instance2.children['instance2_child1'] = 'Instance 2 child 1' 
for key, value in instance2.children.items(): 
    print key + ' -> ' + value 

# Output: instance2_child1 -> Instance 2 child 1 
相关问题