Python类继承:AttributeError:'[SubClass]'对象没有属性'xxx'

Posted

技术标签:

【中文标题】Python类继承:AttributeError:\'[SubClass]\'对象没有属性\'xxx\'【英文标题】:Python class inheritance: AttributeError: '[SubClass]' object has no attribute 'xxx'Python类继承:AttributeError:'[SubClass]'对象没有属性'xxx' 【发布时间】:2012-05-03 08:38:03 【问题描述】:

我有以下基类和子类:

class Event(object):
    def __init__(self, sr1=None, foobar=None):
        self.sr1 = sr1
        self.foobar = foobar
        self.state = STATE_NON_EVENT

# Event class wrappers to provide syntatic sugar
class TypeTwoEvent(Event):
    def __init__(self, level=None):
        self.sr1 = level
        self.state = STATE_EVENT_TWO

在我的代码中,我正在检查 TypeTwoEvent 类的实例,检查我知道基类中存在的字段 - 我希望它默认为值 None。但是,我的代码引发了以下异常:

AttributeError: 'TypeTwoEvent' 对象没有属性 'foobar'

我的印象是基类字段将由子类继承,并且创建子类的实例将实例化基类(并因此调用其构造函数)...

我在这里缺少什么?为什么TypeTwoEvent 没有foobar 属性 - 当派生它的基类具有foobar 属性时?

【问题讨论】:

如下所述,您需要明确指出您希望超类也初始化。但是小心:如果您有任何多重继承,那么实现这一点就变得非常微妙。 【参考方案1】:

你的子类应该是:

class TypeTwoEvent(Event):

    def __init__(self, level=None, *args, **kwargs):
        super(TypeTwoEvent, self).__init__(*args, **kwargs)
        self.sr1 = level
        self.state = STATE_EVENT_TWO

因为你重写了__init__方法,所以如果你想让父行为发生,你需要调用父方法。

记住,__init__ 并不是一个特殊的方法,尽管它的名字很奇怪。它只是对象创建后自动调用的方法。否则就是普通方法,使用普通继承规则。

super(ClassName, self).__init__(arguments, that, goes, to, parents)

是调用父版本方法的语法。

对于*args**kwargs,它只是确保我们捕获传递给__init__ 的所有附加参数并将其传递给父方法,因为您的子方法签名没有这样做,而父方法需要这些参数工作。

【讨论】:

感谢克里斯的编辑。我是法国人,我经常在“它的”和“它的”之间混淆。并不是说我混淆了含义,而是我学会了说话的语言,因此(:-))很容易在我的脑海中将一个声音换成另一个。【参考方案2】:

您正在覆盖父类的构造函数 (__init__)。要扩展它,您需要使用super() 调用显式调用父级的构造函数。

class TypeTwoEvent(Event):
    def __init__(self, level=None, **kwargs):
        # the super call to set the attributes in the parent class
        super(TypeTwoEvent, self).__init__(**kwargs)
        # now, extend other attributes
        self.sr1 = level
        self.state = STATE_EVENT_TWO

请注意,super 调用始终位于子类中 __init__ 方法的顶部。它的位置取决于你的情况和逻辑。

【讨论】:

【参考方案3】:

创建实例时,会调用其__init__ 方法。在这种情况下,即TypeTwoEvent.__init__。不会自动调用超类方法,因为那会非常混乱。

您应该从TypeTwoEvent.__init__ 调用Event.__init__(self, ...)(或使用super,但如果您不熟悉它,请先阅读它,以便您知道自己在做什么)。

【讨论】:

【参考方案4】:

需要从继承类的__init__方法中调用基类的__init__方法。

请参阅here 了解如何执行此操作。

【讨论】:

【参考方案5】:

我也遇到过这个问题,但我把super().__init__() 放在派生类的底部,这就是它不起作用的原因。因为我尝试使用未初始化的属性。

【讨论】:

以上是关于Python类继承:AttributeError:'[SubClass]'对象没有属性'xxx'的主要内容,如果未能解决你的问题,请参考以下文章

Python AttributeError:“类”对象没有属性“名称”-SetUpClass

泡菜模块出错。 AttributeError:类没有属性“__new__”

Python multiprocessing.Pool:AttributeError

python sklearn pipiline fit:“AttributeError:未找到下限”

AttributeError : 类实例没有 __call__ 方法

解决AttributeError: 'Ui_MainWindow' object has no attribute 'show'报错