[英]Python 2.7: strange constructor behavior: changing wrong field
在此代碼中:
# coding=utf-8
def print_tree(node, tree=0):
print(u"|---" * tree + u"-> %s" % node)
for kid in node.children:
print_tree(kid, tree + 1)
class Person(object):
parent = None
first_name = None
last_name = None
children = []
def __str__(self):
return '%s %s' % (self.first_name, self.last_name)
def __unicode__(self):
return u'%s %s' % (self.first_name, self.last_name)
def __init__(self, first_name, last_name, parent=None):
if parent is not None:
if not isinstance(parent, Person):
raise AttributeError('`parent` is not `Person` type!')
self.parent = parent
self.parent.children.append(self)
self.first_name = first_name
self.last_name = last_name
#self.children = []
root = Person('Alan', 'Smith')
p1 = Person('Barbara', 'Smith', root)
p2 = Person('Basia', 'Smith', root)
p3 = Person('Bary', 'Smith', root)
print_tree(root)
如果我從#self.children = []
刪除評論,則示例效果很好。 但是我不明白為什么我必須添加這一行?
在調試器中,我發現self.parent.children.append(self)
行self.parent.children.append(self)
self
也添加到self.children
為什么呢
children
是一個類屬性,您希望它是一個實例屬性。 您應該將children=[]
完全從類范圍中刪除,並只在__init__
方法中保留一個。
在python中,當您在類級別聲明屬性時,這使其成為類屬性(在類的所有實例之間共享)。 在您的情況下,您需要實例屬性。 實例屬性必須在構造函數中創建(您的self.children = []
)。
您遇到了問題,因為在您的代碼中, children
是一個class variable
(在類級別而不是實例級別訪問它時被引用),而不是instance variable
(每個實例都是唯一的)。
因此,您必須添加以下內容:
self.children = []
每次__init__
您的Person
實例。
您要從對象實例引用子對象,因此不能僅將其保留在Class范圍/層中。 因此,您需要self.children = []
因為否則,您不是在引用實例的子代而是類。 (后者的語法為Person.children
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.