2010-11-15 103 views
1

当为我创建的类调用一个对象的新实例时,我的一个类的实例刚刚被覆盖。为什么会这样呢?示例如下。Python类 - 实例被覆盖?

我的类定义如下:

class my_class: 
    attribute = "" 
    examples = [] 
    children = [] 
    d = {} 
    def __init__(self, attribute, e): 
     self.attribute = attribute 
     self.examples = e 

     for ex in self.examples: 
      self.d[ex[-1]] = self.d.get(ex[-1], 0) + 1 

我想提出一个初始实例为这样:

root = my_class(some_attribute, data) 

然后,我创建另一个实例是这样的:

child = my_class(different_attribute, root.examples[somewhere_1:somewhere_2]) 

最后,我最初的'根'现在与'孩子'有些相同,'根'应该没有改变。为什么是这样!?

回答

4

我不认为你用的attributeexampleschildrend你认为你正在做的初始化做。那些现在是类的属性,而不是每个实例的属性。如果您希望类有attributeexampleschildrend其自身的属性的每个实例,则应该写:

class my_class: 
    def __init__(self, attribute, e): 

     self.attribute = attribute 
     self.examples = e 
     self.children = [] 
     self.d = {} 

     for ex in self.examples: 
      self.d[ex[-1]] = self.d.get(ex[-1], 0) + 1 
+0

啊!你是对的。非常感谢你清除那个 – 2010-11-15 00:19:55

1

当你定义在类定义的变量,它们是类属性。

>>> my_class.examples is my_class().examples 
True 

is检查它们是完全相同的对象,而不是只是相等。例如,True == 1,但True is not 1。)

作为list S和dict s为可变的,这意味着变化my_class.examplesroot.exampleschild.examples将反映在所有其他。

你应该做这样的事情的方式是,设置它的构造函数中:

class my_class: 
    def __init__(self, attribute, e): 
     self.attribute = attribute 
     self.examples = e 
     self.children = [] 
     self.d = {} 

     for ex in self.examples: 
      self.d[ex[-1]] = self.d.get(ex[-1], 0) + 1 

你可能还希望与self.examples = e[:]这将使列表的浅副本替换self.examples = e。否则:

>>> data 
[1, 2, 3, 4, 5] 
>>> root = my_class(some_attribute, data) 
>>> root.examples 
[1, 2, 3, 4, 5] 
>>> data += [6, 7] 
>>> root.examples 
[1, 2, 3, 4, 5, 6, 7] 
>>> # ... because: 
>>> root.examples is data 
True 

旁注:推荐的Python风格将您的类作为MyClass。我建议你阅读PEP 8.