4 回答

TA貢獻(xiàn)1866條經(jīng)驗 獲得超5個贊
你在做什么都是胡說八道。只是讓他們一類和使用或者 add_child()
和remove_child()
或 set_parent()
,但不能同時使用。

TA貢獻(xiàn)1784條經(jīng)驗 獲得超2個贊
Martin Fowler,Kent Beck等作者的《重構(gòu):改進(jìn)現(xiàn)有代碼的設(shè)計》一書中描述了稱為“雙向關(guān)聯(lián)”的問題。在書中解決問題的方式是通過為一個類分配對另一個類的完全控制權(quán)。首先,您需要確定此處必須控制哪個類。我認(rèn)為,在您的情況下,孩子應(yīng)該受控制,這與現(xiàn)實世界的工作方式背道而馳。然后,您需要允許控制器訪問受控對象的私有成員。在C ++中,您可以通過使一個類成為另一個類的“朋友”來解決此問題。在具有真正隱私權(quán)的其他語言中,您可以創(chuàng)建一個公共訪問器方法,并在文檔中明確聲明該方法只能由一個類使用。但是在Python中,您不受這種方式的限制??紤]以下代碼:
class Child(object):
def __init__(self, parent=None):
self._parent = None
self.set_parent(parent)
def set_parent(self, parent):
# Remove self from old parent's children
if self._parent:
self._parent._children.remove(self)
# Set new parent
self._parent = parent
# Add self to new parent's children
if self._parent:
self._parent._children.append(self)
class Parent(Child):
def __init__(self, parent=None):
super(Parent, self).__init__(parent)
self._children = []
def add_child(self, child):
if child not in self._children:
child.set_parent(self)
def remove_child(self, child):
if child in self._children:
child.set_parent(None)
c1 = Child()
c2 = Child()
p1 = Parent()
p2 = Parent()
p1.add_child(c1)
p1.add_child(c2)
print "1:"
print "c1._parent", c1._parent
print "c2._parent", c2._parent
print "p1._children", p1._children
print "p2._children", p2._children
p2.add_child(c1)
print "2:"
print "c1._parent", c1._parent
print "c2._parent", c2._parent
print "p1._children", p1._children
print "p2._children", p2._children
c1 = Child()
c2 = Child()
p1 = Parent()
p2 = Parent()
c1.set_parent(p1)
c2.set_parent(p1)
print "3:"
print "c1._parent", c1._parent
print "c2._parent", c2._parent
print "p1._children", p1._children
print "p2._children", p2._children
c1.set_parent(p2)
print "4:"
print "c1._parent", c1._parent
print "c2._parent", c2._parent
print "p1._children", p1._children
print "p2._children", p2._children

TA貢獻(xiàn)1826條經(jīng)驗 獲得超6個贊
parent.add_child(child)
和child.set_parent(parent)
(應(yīng)該是)相同的操作。讓其中一個委托給另一個,或者讓兩個委托給第三個方法,或者只是刪除其中一個。這將使事情更容易推理。
解決此問題的快速而骯臟的_add_child
方法是添加一個孩子而不觸碰孩子的parent
屬性的方法。您set_parent
可以使用它來避免無限遞歸。但是,類似之類的方法_add_child
或您當(dāng)前使用的方法remove_child
容易出錯,因為它們破壞了雙向鏈接的對稱性。一方對關(guān)系的看法與另一方暫時不同,很容易使雙方不同步。這將會是清潔的落實add_child
和set_parent
在方法方面,這種關(guān)系的更新雙方的一次。
不請自來的額外建議:請勿使用雙下劃線前綴。它不會阻止類外部的代碼訪問該屬性,無論如何,您都不應(yīng)嘗試在Python中阻止這種行為。只需使用一個下劃線,表明它不屬于該類的公共API。
添加回答
舉報