python - 如何将 parent 和 child 相互联系起来?

标签 python parent-child parent children

有两个简单的类;一个只有 parent 属性,一个同时具有 parentchildren 属性。 这意味着同时具有 parentchildren 的那个继承自只有 parent 的那个。

这是只有 parent 属性的类。 我们称它为 Child,因为它只能是 child ,不能是 parent 。 我将使用方法 set_parent() 使其更清晰,但我会在实际代码中使用 setter。

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.remove_child(self)
        # Set new parent
        self.__parent = parent
        # Add self to new parent's children
        if self.__parent:
            self.__parent.add_child(self)

该代码非常有意义,而且似乎工作得很好。 这是,如果 Parent 类看起来像这样简单:

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:
            self.__children.append(child)

    def remove_child(self, child):
        if child in self.__children:
            self.__children.remove(child)

但是,我希望能够调用 my_parent.add_child(my_child) 并将 my_child 的父属性设置为 my_parent从它的老 parent 的 child 中删除 my_child

我似乎无法弄清楚如何实际设计代码,我尝试的一切都会变成 set_parent()add_child 之间的无限循环()remove_child()

我知道这个网站不适合其他人为我编写代码,但至少有人可以提供一些提示吗? 我的大脑就是无法处理这个问题,我已经连续思考了 30 分钟,但没有完成任何事情。 帮助表示赞赏!

最佳答案

这个问题被称为“双向关联”,在 Martin Fowler、Kent Beck 和其他几位作者所著的“重构:改进现有代码的设计”一书中有所描述。书中解决问题的方法是让其中一个类完全控制另一个类。首先,您需要决定必须控制哪个类。我相信在您的情况下, child 应该处于控制之中,这与现实世界的运作方式相悖。然后,您需要允许 Controller 访问受控的私有(private)成员。在 C++ 中,您可以通过使其中一个类成为另一个类的“ friend ”来解决这个问题。在其他具有真正隐私的语言中,您可以创建一个公共(public)访问器方法,并在文档中明确说明它仅供一个类使用。然而,在 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

关于python - 如何将 parent 和 child 相互联系起来?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17092970/

相关文章:

javascript - 从父窗口的新选项卡中的弹出窗口打开链接

python - 如何使用 pandas 和 sqlalchemy 进行分块读写

Python。函数旁边的另一个括号

python - xarray : reshape data, 拆分维度

python - 将多个 Python 子解释器嵌入到 C 程序中

java - 在战舰游戏中创建船只

html - 在表中选择具有特定类的第一个 child 并将其隐藏

php - Wordpress 子主题需要从父主题中提取多个样式表

jQuery 在父窗口中选择元素

javascript - 是否可以在 iFrame 中使用 JavaScript 获取 iFrame 父页面的 referrer?