当一个子类用__init __()调用super()时,哪个/什么是超类的对象?

时间:2016-01-10 14:01:40

标签: python python-2.7 inheritance subclass

根据Learn Python The Hard Way ex44以及super()__init__的使用说明:

class Child(object): 
    def __init__(self, stuff):
        self.stuff = stuff
        super(Child, self).__init__()
  

这与上面的Child.altered示例非常相似,   除了我在__init__之前设置一些变量之前   Parent使用Parent.__init__.

进行初始化

因此实例化Child也会导致Parent的实例化。但是这个实例化是什么/在哪里?给出:

c = Child()

where {什么是Parent对象?

2 个答案:

答案 0 :(得分:3)

super(Child, self)为您提供self指向的对象作为Child的父类的实例(Parent)。

__init__的{​​{1}}方法中,您首先要做一些事情(Child),然后在您的self.stuff = stuff 上调用__init__方法Parent指向的Child对象

您没有明确地实例化self对象,但由于继承,每个Parent 都是 Child

  

@timgeb一个实用的例子,或以这种方式使用super()的理由会有所帮助。

当然,让我们看一个简单的例子。我们假设您正在构建邮政服务申请表。该服务提供多种物品,如包裹,信件或明信片。每个项目共享一些属性。为了简单起见,让我们说他们共享接收者的名字(在现实世界的应用程序中,你可能需要更多属性,例如接收者的完整地址)。

Parent

这似乎工作正常。但是,我们的>>> class MailItem(object): ... def __init__(self, receiver_name): ... self.receiver_name = receiver_name ... >>> m = MailItem('Pyderman') >>> m.receiver_name 'Pyderman' 太过不明确了。如果物品是包裹怎么办?然后我们肯定会关心它的重量。另一方面,如果物品是明信片,则重量将无关紧要。让我们为名为MailItem的包创建一个子类,该类继承自Package。每个MailItem对象都是-a Package,但它会存储有关其权重的额外信息。

MailItem

当我们实例化>>> class Package(MailItem): ... def __init__(self, receiver_name, weight): ... # treat the package as a MailItem and call the MailItem initializier ... super(Package, self).__init__(receiver_name) ... # store extra information about the weight in some arbitrary unit ... self.weight = weight 时,我们要做的第一件事是调用Package的初始值设定项,因为每个MailItem也是Package。这不会创建另一个MailItem对象,而是在我们的新MailItem对象上调用__init__ MailItem方法。在此示例中,我们可以通过将Package的初始化程序中的行self.receiver_name = receiver_name复制到MailItem的初始化程序而不是使用Package来实现相同的目的,但这样做会是重复的代码,反对不要重复自己的原则。

让我们实例化super以查看正在运行的代码。

Package

正如您所看到的,对象>>> p = Package('Pyderman', 200) >>> p.receiver_name 'Pyderman' >>> p.weight 200 确实有p,因为receiver_name的初始化程序通过Package调用MailItem初始化程序}。

冒着重复自己的风险,让事情变得清晰: 我们只使用super(Package, self).__init__(receiver_name)创建一个Package对象,而不是另外的p = Package('Pyderman', 200)个对象。每个MailItem对象都是-a Package,Python会告诉您:

MailItem

当然,每个>>> isinstance(p, MailItem) True 也是Package

Package

但是,并非每个>>> isinstance(p, Package) True 都是-a MailItem

Package

以这种方式思考:每只鳄鱼都是爬行动物,但不是每只爬行动物都是鳄鱼。

答案 1 :(得分:2)

没有实例化,初始化 - 仔细阅读你引用的段落,你会看到它只提到后者。初始化(有时在历史上也称为构造)是将空实例构建为给定类型的可用对象的过程。

Parent.__init__会产生一个可用的Parent对象; Child.__init__构建于此基础上以创建可用的Child对象。因此,每个Child对象都是一个有效的Parent对象。