使用__init__的属性继承

61 投票
5 回答
74463 浏览
提问于 2025-04-17 10:11

我是一名Java程序员,刚开始学习Python。来看这个例子:

class Person():
    def __init__(self, name, phone):
        self.name = name
        self.phone = phone

class Teenager(Person):
    def __init__(self, name, phone, website):
        self.name=name
        self.phone=phone
        self.website=website

我相信这里有很多多余的代码(我知道在Java中,上面的代码也有很多冗余)。

哪些部分是多余的,因为这些属性已经从父类继承过来了呢?

5 个回答

23

到目前为止,所有的例子都是针对Python 2.x的,但这里有一个适用于Python 3.x的解决方案,它使用了更简短的super()写法,并且不需要从object继承。

class Person:
    def __init__(self, name, phone):
        self.name = name
        self.phone = phone

class Teenager(Person):
    def __init__(self, name, phone, website):
        super().__init__(name, phone)
        self.website = website
30

我喜欢用一种稍微干净一点的方法来做这个:

class Teenager(Person):
        def __init__(self, *args, **kwargs):
           self.website=kwargs.pop('website')
           super(Teenager, self).__init__(*args, **kwargs)

在这个例子中差别不大,但如果你的 __init__ 方法有很多参数的话,这样做会让事情变得简单很多。

75

在写Python类的__init__函数时,记得要调用它的父类(也叫超类)的__init__函数。这样做可以把相关的属性直接传给父类,你的代码看起来会像这样:

class Person(object):
    def __init__(self, name, phone):
        self.name = name
        self.phone = phone
class Teenager(Person):
    def __init__(self, name, phone, website):
        Person.__init__(self, name, phone)
        self.website=website

正如其他人提到的,你可以把这一行

Person.__init__(self, name, phone)

替换成

super(Teenager, self).__init__(name, phone)

这样,代码的效果是一样的。这是因为在Python中,instance.method(args)其实就是Class.method(instance, args)的简写。如果你想使用super,你需要确保在定义Person类时,把object作为基类,就像我在代码中做的那样。

关于如何使用super这个关键词,Python文档里有更多信息。在这个情况下,重要的是它告诉Python去找self的父类中,不是Teenager__init__方法。

撰写回答