我正在使用python中的OOP进行一些练习,而且我遇到了一个我的非计算机科学家头脑无法理解的问题。我确定这只是因为我对OO缺乏经验,但我似乎无法在任何地方找到答案。
所以我有三节课。一个名为tester的类,它应该包含一个名为group的唯一对象,该对象应该包含一个名为atom的对象列表。我的问题是,每当我创建多个组时,它们似乎都具有相同的列表对象。因此,每当我将一个原子附加到列表时,它就会附加到所有组的列表中。我的代码是:
count = 0
testers = []
class atom:
def __init__(self):
pass
class group:
myList = list()
def __init__(self):
pass
def createAtom(self):
self.myList.append(atom())
class tester:
def __init__(self):
self.myGroup = group()
for k in range(4):
testers.append(tester())
print testers[k].myGroup
for t in testers:
t.myGroup.createAtom()
print t.myGroup.myList
我希望这会为每个组创建一个新列表,并且这会为每个组添加一个原子。而是创建一个输出如下。
<__main__.group instance at 0x02C2E058>
<__main__.group instance at 0x02C2E0A8>
<__main__.group instance at 0x02C2E0F8>
<__main__.group instance at 0x02C2E148>
[<__main__.atom instance at 0x02C2E170>]
[<__main__.atom instance at 0x02C2E170>, <__main__.atom instance at 0x02C2E198>]
[<__main__.atom instance at 0x02C2E170>, <__main__.atom instance at 0x02C2E198>, <__main__.atom instance at 0x02C2E1C0>]
[<__main__.atom instance at 0x02C2E170>, <__main__.atom instance at 0x02C2E198>, <__main__.atom instance at 0x02C2E1C0>, <__main__.atom instance at 0x02C2E1E8>]
单个列表获取所有四个原子。我为可能很差的代码道歉。如果它有任何帮助,我使用的是python portable 2.7.5.1。任何有关这方面的见解将不胜感激。
由于
答案 0 :(得分:3)
您的列表是一个类属性,在所有实例之间共享:
class group:
myList = [] # class attribute
def __init__(self):
pass
相反,将它设为实例属性,为每个类的实例分开:
class group:
def __init__(self):
self.myList = [] # instance attribute
请注意,我已根据 thefourtheye 的评论将list()
替换为[]
。阴影内置插件(例如,拥有自己的列表或名为list
的其他对象)是不好的做法,但如果规则被破坏,这可以避免副作用。
答案 1 :(得分:1)
您已将group.myList
设为class attribute,并由所有实例共享。
class group:
#myList = list() # <--- this defines a 'class' attribute
# which is shared by all instances of 'group'
def __init__(self):
self.myList = list() # <--- do this instead to create an instance attribute
def createAtom(self):
self.myList.append(atom())
答案 2 :(得分:0)
将mylist = list()
中的class group
移至__init__
的{{1}}。
这样做会使class group
每次创建新的组实例时都创建一个新列表。否则,您所做的就是创建一个类级变量(不是实例级),它将在同一个类的所有实例之间共享。
将类变量视为该类的所有实例的“蜂巢思维”(想想星际迷航中的博格)结构。对类变量所做的任何更改都将对该类型的所有对象可见。
另一方面,如果要创建一个实例变量(在group
中初始化的变量),那么每个实例都有自己的变量值。因此,一个实例对其变量所做的任何更改对于同一类型的其他实例都是不可见的