如何在Python中从继承类中设置和获取父类属性?

29

我有Family类和其继承的Person类。我该如何从Person类中获取familyName属性?

class Family(object):
    def __init__(self, familyName):
        self.familyName = familyName

class Person(Family):
    def __init__(self, personName):
        self.personName = personName

例如,假设有以下这些 FamilyPerson 对象:
strauss = Family('Strauss')
johaness = Person('Johaness')
richard = Person('Richard')

我想要做类似以下这样的事情:

print richard.familyName

并获取'Strauss'。我该怎么做?


这不是正确使用继承的方式。继承代表了“是一个”(IS-A)的关系,但一个人并不是一种家庭。 - Barmar
2个回答

48

你不能。

实例只会继承父类的方法和属性,而不是实例属性。你不应该把两者混淆。

strauss.familyName是一个Family实例的实例属性。而Person实例将会拥有它们自己的familyName属性。

通常情况下,你会编写Person构造函数来接受两个参数:

class Person(Family):
    def __init__(self, personName, familyName):
        super(Person, self).__init__(familyName)
        self.personName = personName

johaness = Person('Johaness', 'Strauss')
richard = Person('Richard', 'Strauss')

另一种方法是让 Person 持有一个对 Family 实例的引用:

class Person(object):
    def __init__(self, personName, family):
        self.personName = personName
        self.family = family

使用方法如下,其中Person不再继承自Family

strauss = Family('Strauss')
johaness = Person('Johaness', strauss)
richard = Person('Richard', strauss)

print johaness.family.familyName

1
选项的呈现很好! - T. Brian Jones
我知道这是7年前的事了,但我找到了一种获取实例属性的方法,即class_name.init(self)。 - Aditya Kendre
1
@AdityaKendre:那样是行不通的,因为在这里 Family.__init__() 接受一个参数 familyName。这就是为什么正确的修复方法是将 familyName 参数添加到 Person.__init__() 方法中,然后调用 super().__init__(familyName)。如果您传递了额外的参数,那么您的 class_name.__init__(self) 版本也可以工作,因此 Family.__init__(self, familyName)。那只是调用父类的另一种方式,而 super().__init__() 在使用多重继承时仍将继续工作。 - Martijn Pieters

6
除了Martijns的建议外,您还可以从Family实例中创建Person,这样可以让家庭跟踪其成员:
class Person(object):
    def __init__(self, person_name, family):
        self.person_name = person_name
        self.family = family

    def __str__(self):
        return ' '.join((self.person_name, self.family.family_name))

class Family(object):
    def __init__(self, family_name):
        self.family_name = family_name
        self.members = []

    def add_person(self, person_name):
        person = Person(person_name, self)
        self.members.append(person)
        return person

    def __str__(self):
        return 'The %s family: ' % self.family_name + ', '.join(str(x) for x in self.members)

使用方式如下:

>>> strauss = Family('Strauss')
>>> johannes = strauss.add_person('Johannes')
>>> richard = strauss.add_person('Richard')
>>> 
>>> print johannes
Johannes Strauss
>>> print richard
Richard Strauss
>>> print strauss
The Strauss family: Johannes Strauss, Richard Strauss

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接