【问题标题】:How do I change the parent class instance/attributes of a class object in Python?如何在 Python 中更改类对象的父类实例/属性?
【发布时间】:2018-07-27 05:58:55
【问题描述】:

我已经成功使用 Python 在 Excel 中编写批处理脚本几个月了,甚至更长时间,但我仍然没有真正理解面向对象的编程。

假设我有以下代码,除了有更多的人/家庭(比如说,50 个家庭)和更多的家庭属性,而不仅仅是姓氏、地址和家庭规模(比如说,10 个属性)。

class Family():
    def __init__(self, family_id, last_name, address, family_size):  
        self.family_id = family_id  
        self.last_name = last_name  
        self.address = address
        self.family_size = family_size  

class Person(Family):
    def __init___(self, family_id, last_name, address, family_size, person_id, first_name,  
                  middle_name):
        super().__init__(id, last_name, address, family_size)
        self.person_id = person_id
        self.first_name = first_name
        self.middle_name = middle_name

jones1 = Family(2, "Jones", "456 Main Street", 1)
bob1 = Person(1, "Smith", "123 Main Street", 1, 1, "Bob", "James")    
alice1 = Person(2, "Jones", "456 Main Street", 1, 2, "Alice", "Mary")

现在假设我实例化了两个名为 Bob 和 Alice 的对象(人)。他们来自两个不同的家庭。但是,假设我希望 Bob 和 Alice 结婚,这意味着他们中的一个人放弃了自己的家庭并加入了另一个人的家庭。

在代码方面,我该怎么做?我知道我可以输入:

 bob1.last_name = "Jones"  

现在 Bob 有了 Alice 的姓氏。但是必须有比手动覆盖每个类属性更简单的方法。我觉得我错过了关于家庭对象 (jones1) 的一些非常简单的事情,但是我如何让 Bob 成为 Jones 家庭的一员?

编辑:为了澄清反对意见,这是一个练习,与我的工作没有直接关系。我不熟悉 OOP 和 Stack Overflow;如果您有任何关于我如何更好地表达我的问题的 cmets,除了发布更少的实际代码错误之外,请在 cmets 中告诉我。

【问题讨论】:

  • class Person(Family) 不是一个合理的子类关系——它暗示一个人一个家庭。你需要组合,而不是子类化。
  • 另外,即使忽略" 错字,这段代码也不会运行,并且不清楚它是如何supposed 工作的。您的Person.__init__ 没有任何它试图传递给super().__init__ 的变量,然后它尝试使用id,它也没有作为变量。然后,为了更好的衡量标准,您使用错误数量的参数调用构造函数。
  • 我在运行中提出了代码,作为我实际使用的简化的理论示例;我没试过运行它。我一直在寻找更多的理论方向,以正确地使用 OOP 实现家庭成员。

标签: python class oop subclass


【解决方案1】:

首先,我对您的代码有一些建议。

  • 最好使用继承自对象class Foo(object)的新样式类。

  • 对于新的样式类,使用super(ChildClass, self).__init__()覆盖init方法。

  • Family 不应该是基类,而是 Person 所属的另一个类。基类的含义是子类是基类的子类型。显然,人不是家庭的子类型。我们可以说狗是动物的一个子类型。

我对您的代码做了一些调整。您可能需要根据自己的想法进行修改。

class Family(object):
    def __init__(self, family_id, last_name, address, family_size):  
        self.family_id = family_id  
        self.last_name = last_name  
        self.address = address
        self.family_size = family_size  

class Person(object):
    def __init___(self, family_id, last_name, address, family_size, person_id, first_name,  
              middle_name):
        self.id = ...
        self.last_name = ...
        ...
        self.person_id = person_id
        self.first_name = first_name
        self.middle_name = middle_name

    def join_family(self, new_family):
        self.family.family_size -= 1
        self.family = new_family
        new_family.family_size += 1

    def marry_to(self, person):
        self.join_family(person.family)

family_smith = Family(1, "Smith", "789 Main Street", 1)
family_jones1 = Family(2, "Jones", "456 Main Street", 1)
bob1 = Person(1, "Smith", "123 Main Street", 1, 1, "Bob", "James")    
alice1 = Person(2, "Jones", "456 Main Street", 1, 2, "Alice", "Mary")

然后鲍勃结婚并加入了爱丽丝的家庭

bob1.marry_to(alice1)

bob1.join_family(family_jones1)

【讨论】:

    【解决方案2】:

    继承是一个是一个关系。一个人不是一个家庭,而是属于一个家庭,所以这里的继承是可疑的。

    两个不同的人可以属于同一个家庭,这不能通过继承实现 => 你需要一个 1-n 的父子类型关系。一种常见的方法是在家庭中包含一个容器(例如一个集合或一个列表),和/或亲自引用家庭:

    class Family:
        def __init__(self, id, last_name, address):  
            self.id = id  
            self.last_name = last_name  
            self.address = address
            self.family_members = set()
        def add(self, member):
            member.family = self
            self.family_members.add(member)
        def remove(self, member):
            member.family = self
            self.family_members.remove(member)
    
    class Person:
        def __init__(self, first_name, middle_name, family):
            self.first_name = first_name
            self.middle_name = middle_name
            family.add(self)
        def change_family(self, new_family):
            self.family.remove(self)
            new_family.add(self)
    

    我已将 change_family 方法添加到 person,这是 Alice 嫁给 Bob 所需要的...


    经典的继承示例是 Animal、Cat 和 Dog。一只猫一种动物(狗也是),两只不同的猫是不同的动物……

    【讨论】:

    • 感谢您的简明解释。 remove(self) 是我必须自己创建的方法,比如 family.add(self),还是内置的,比如 list.remove(item)?
    • @Strangely: 这是我忘记写在这里的方法:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-20
    • 2021-09-05
    • 1970-01-01
    • 2022-06-11
    • 2021-12-17
    • 1970-01-01
    • 2021-11-07
    相关资源
    最近更新 更多