为了账号安全,请及时绑定邮箱和手机立即绑定

如何将父母与子女彼此联系起来?

如何将父母与子女彼此联系起来?

人到中年有点甜 2021-03-30 08:07:46
有两个简单的类;一个仅具有parent属性,一个同时具有parent和children属性。这意味着,一个既parent和children继承了一个只parent。这是只有parent属性的类。之所以称呼它是Child因为它只能是一个孩子,而不能是父母。我将使用一种方法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同时消除my_child从它的老父母的孩子。我似乎无法弄清楚如何实际设计的代码,一切我尝试将变成之间的无限循环set_parent()和add_child()或remove_child()。我知道这个网站并不意味着其他人可以为我编写代码,但是至少有人可以给我一些提示吗?我的大脑无法解决这个问题,我已经连续思考了30分钟,却没有做任何事情。帮助赞赏!
查看完整描述

4 回答

?
心有法竹

TA贡献1866条经验 获得超5个赞

你在做什么都是胡说八道。只是让他们一类和使用或者 add_child()remove_child()  set_parent(),但不能同时使用。


查看完整回答
反对 回复 2021-04-01
?
一只斗牛犬

TA贡献1784条经验 获得超2个赞

Martin Fowler,Kent Beck等作者的《重构:改进现有代码的设计》一书中描述了称为“双向关联”的问题。在书中解决问题的方式是通过为一个类分配对另一个类的完全控制权。首先,您需要确定此处必须控制哪个类。我认为,在您的情况下,孩子应该受控制,这与现实世界的工作方式背道而驰。然后,您需要允许控制器访问受控对象的私有成员。在C ++中,您可以通过使一个类成为另一个类的“朋友”来解决此问题。在具有真正隐私权的其他语言中,您可以创建一个公共访问器方法,并在文档中明确声明该方法只能由一个类使用。但是在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


查看完整回答
反对 回复 2021-04-01
?
跃然一笑

TA贡献1826条经验 获得超6个赞

parent.add_child(child)child.set_parent(parent)(应该是)相同的操作。让其中一个委托给另一个,或者让两个委托给第三个方法,或者只是删除其中一个。这将使事情更容易推理。

解决此问题的快速而肮脏的_add_child方法是添加一个孩子而不触碰孩子的parent属性的方法。您set_parent可以使用它来避免无限递归。但是,类似之类的方法_add_child或您当前使用的方法remove_child容易出错,因为它们破坏了双向链接的对称性。一方对关系的看法与另一方暂时不同,很容易使双方不同步。这将会是清洁的落实add_childset_parent在方法方面,这种关系的更新双方的一次。

不请自来的额外建议:请勿使用双下划线前缀。它不会阻止类外部的代码访问该属性,无论如何,您都不应尝试在Python中阻止这种行为。只需使用一个下划线,表明它不属于该类的公共API。


查看完整回答
反对 回复 2021-04-01
  • 4 回答
  • 0 关注
  • 219 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号