从超类对象初始化子类实例

Posted

技术标签:

【中文标题】从超类对象初始化子类实例【英文标题】:Initializing a Subclass Instance from a Superclass Object 【发布时间】:2016-06-13 01:35:36 【问题描述】:

logging.Logger 的文档指出:

请注意,Logger 永远不会直接实例化,而是始终通过模块级函数 logging.getLogger(name)

这让我想到了以下问题(我将切换到一些Foo 类而不是logging.Logger,因为我想问一下一般的原理)。


假设有一些类Foo,有几个属性和方法:

class Foo:
    def method_0(self..):
        ...

    def method_1(self..):
        ...

    def method_n(self..):
        ...

我想继承Foo,并且只专门化其中的几个方法。

class SubFoo(Foo):
    def method_1(self, ...):
        ...
        # Or super - not the point of the question.
        Foo.method_1(self, ...)

    ...

问题在于Foo 没有可用的构造函数,只有创建Foo 类型对象的方法,例如通过getFooSubFoo 的“Foo”部分需要是“已批准”Foo 对象,我不知道如何强制将 SubFoos Foo 部分设为“已批准”对象。

注意

对于Foo 的子类化显然有几个解决方法,例如,组合、猴子修补、与__dict__/gettatr 的巧妙游戏等。尽管如此,这个问题是关于子类化的。

【问题讨论】:

你应该使用__new__方法在__init__之前构造子类。我发现docs.scipy.org/doc/numpy/user/… 非常有用。 【参考方案1】:

您误解了继承。要创建 SubFoo 的实例,您只需像对任何其他类一样实例化它:SubFoo()

Python 没有构造函数,在任何情况下,未在子类上定义的方法都会自动继承超类版本,而无需您做任何事情。

【讨论】:

谢谢,但我真的不明白你的回答。当我对某些东西进行子类化时,我的子类的代码__init__(我显然错误地称为ctor)调用超类的__init__(使用super,或其他方式)。我不明白当我在这里调用SubFoo 时,如何创建一个Foo 对象(不过,我确实知道如何通过组合来实现它——我只会调用getLogger 的等价物)。跨度> 不会,会创建一个 SubFoo。这就是继承的意义:一个 SubFoo is-a Foo. 非常感谢,我现在明白你的回答了。不过,重点仍然是,我不是从超类实例创建子类实例,不是吗?大概 getLogger 有一些副作用(如果没有,我假设的 getFoo 有),所以我必须用一些“批准”的超类对象来实例化它。 尽管如此,感谢关于超类的 init 与 Liskov is-a 模糊不清的更正。赞赏。

以上是关于从超类对象初始化子类实例的主要内容,如果未能解决你的问题,请参考以下文章

子类是不是从超类继承私有实例变量

当子类使用Object变量实例化时,无法从超类访问方法

如何键入提示 Python 函数返回从超类派生的任何类的实例?

OWL:如何从超类继承两个类之间的属性关系?

如果我使用Superclass初始化子类对象,为什么该对象具有子类的属性,但是超类的方法?

ruby 如何从超类初始化关键字参数(对依赖注入很有用)