当我为我创建的类调用一个对象的新实例时,我的一个类实例就被覆盖了。为什么会这样?示例如下。
我的课程定义如下:
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])
最后,我的初始'root'现在与'child'在某种程度上相同,其中'root'应该保持不变。这是为什么!?
答案 0 :(得分:6)
我认为您正在使用attribute
,examples
,children
和d
初始化您认为自己正在做的事情。这些现在是类的属性,而不是每个实例的属性。如果您希望类的每个实例都有attribute
,examples
,children
和d
的自己的属性,那么您应该写:
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
答案 1 :(得分:2)
在类定义中定义变量时,它们是类属性。
>>> my_class.examples is my_class().examples
True
(is
检查它们是完全相同的对象,而不仅仅是相等的。例如,True == 1
,但是True is not 1
。)
由于list
和dict
s是可变的,这意味着my_class.examples
或root.examples
或child.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。