简体   繁体   English

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

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

I have the following base class and subclass:我有以下基类和子类:

class Event:
    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

Further on in my code, I am inspecting an instance of a TypeTwoEvent class, checking for a field I know exists in the base class - I expected it to be defaulted to value None .在我的代码中,我正在检查TypeTwoEvent类的实例,检查我知道基类中存在的字段 - 我希望它默认为值None However, my code raises the following exception:但是,我的代码引发了以下异常:

AttributeError: 'TypeTwoEvent' object has no attribute 'foobar' AttributeError:“TypeTwoEvent”对象没有属性“foobar”

I was under the impression that the base class fields would be inherited by the subclass and that creating an instance of a subclass will instantiate the base class (and thus invoke its constructor) ...我的印象是基类字段将由子类继承,并且创建子类的实例将实例化基类(并因此调用其构造函数)......

What am I missing here?我在这里想念什么? Why does TypeTwoEvent not have a foobar attribute - when the base class from which it is derived has a foobar attribute?为什么TypeTwoEvent没有foobar属性 - 当派生它的基类具有foobar属性时?

Your subclass should be:你的子类应该是:

class TypeTwoEvent(Event):

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

Because you override the __init__ method, so you need to call the parent method if you want the parent behavior to happen.因为您覆盖了__init__方法,所以如果您希望父行为发生,则需要调用父方法。

Remember, __init__ is not a special method dispite its strange name.请记住, __init__并不是一个特殊的方法,尽管它的名字很奇怪。 It's just the method automatically called after the object is created.它只是对象创建后自动调用的方法。 Otherwise it's an ordinary method, and ordinary inheritance rules apply.否则它是一个普通的方法,并且应用普通的继承规则。

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

is the syntax to call the parent version of the method.是调用方法的父版本的语法。

For *args and **kwargs , it just ensures we catch all additional arguments passed to __init__ and pass it to the parent method, as you child method signature didn't do it and the parent need these arguments to work.对于*args**kwargs ,它只是确保我们捕获传递给__init__的所有附加参数并将其传递给父方法,因为您的子方法签名没有这样做,而父方法需要这些参数才能工作。

You're overriding the constructor ( __init__ ) of the parent class.您正在覆盖父类的构造函数 ( __init__ )。 To extend it, you need to explicitly call the constructor of the parent with a super() call.要扩展它,您需要使用super()调用显式调用父级的构造函数。

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

Note that the super call is not always at the top of the __init__ method in your sub-class.请注意, super调用并不总是位于子类中__init__方法的顶部。 Its location depends on your situation and logic.它的位置取决于你的情况和逻辑。

When the instance is created, its __init__ method is called.创建实例时,会调用其__init__方法。 In this case, that is TypeTwoEvent.__init__ .在这种情况下,即TypeTwoEvent.__init__ Superclass methods will not be called automatically because that would be immensely confusing.超类方法不会被自动调用,因为那会非常混乱。

You should call Event.__init__(self, ...) from TypeTwoEvent.__init__ (or use super , but if you're not familiar with it, read up on it first so you know what you're doing).您应该从TypeTwoEvent.__init__调用Event.__init__(self, ...) (或使用super ,但如果您不熟悉它,请先阅读它,以便您知道自己在做什么)。

You need to call the __init__ method of the base class from the __init__ method of the inherited class.您需要从继承类的__init__方法中调用基类的__init__方法。

See here for how to do this.请参阅此处了解如何执行此操作。

I've had the same problem, but in my case I put super().__init__() on the bottom of my derived class and that's why it doesn't work.我遇到了同样的问题,但就我而言,我将super().__init__()放在派生类的底部,这就是它不起作用的原因。 Because I tried to use attributes that are not initialized.因为我尝试使用未初始化的属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM