簡體   English   中英

Python 2.7:奇怪的構造函數行為:更改錯誤的字段

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM