python类继承:attributeError:”[subclass]”对象没有属性”xxx”

Python class inheritance: AttributeError: '[SubClass]' object has no attribute 'xxx'

我有以下基类和子类:

1
2
3
4
5
6
7
8
9
10
11
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' object has no attribute 'foobar'

我的印象是,基类字段将由子类继承,创建子类的实例将实例化基类(从而调用其构造函数)。

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


你的子类应该是:

1
2
3
4
5
6
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__并不是一种特殊的方法,它的名字很奇怪。它只是创建对象后自动调用的方法。否则,它是一个普通的方法,并且应用普通的继承规则。

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

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

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


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

1
2
3
4
5
6
7
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__方法的顶部。它的位置取决于你的情况和逻辑。


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

你应该从TypeTwoEvent.__init__Event.__init__(self, ...)打电话(或者用super打电话,但是如果你不熟悉的话,先读一下,这样你就知道你在做什么了)。


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

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


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