35

次の基本クラスとサブクラスがあります。

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があるのに、属性がないのはなぜですか?foobarfoobar

4

5 に答える 5

37

サブクラスは次のようにする必要があります。

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)

メソッドの親バージョンを呼び出す構文です。

*argsandの場合**kwargs、渡されたすべての追加引数を確実にキャッチ__init__して親メソッドに渡します。これは、子メソッドのシグネチャがそれを行わず、親がこれらの引数を機能させる必要があるためです。

于 2012-04-22T14:18:11.177 に答える
4

__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__その場所は、状況とロジックによって異なります。

于 2012-04-22T14:11:05.450 に答える
2

インスタンスが作成されると、その__init__メソッドが呼び出されます。この場合、それはTypeTwoEvent.__init__です。スーパークラスのメソッドは、非常に混乱するため、自動的には呼び出されません。

Event.__init__(self, ...)から電話する必要がありますTypeTwoEvent.__init__(またはを使用superしますが、慣れていない場合は、最初にそれを読んで、何をしているのかを理解してください)。

于 2012-04-22T14:11:00.590 に答える
1

継承されたクラス__init__のメソッドから基本クラスのメソッドを呼び出す必要があります。__init__

これを行う方法については、こちらをご覧ください。

于 2012-04-22T14:09:37.877 に答える
0

これにも問題がありましたsuper().__init__()が、派生クラスの一番下に配置したため、機能しません。初期化されていない属性を使用しようとするためです。

于 2017-07-23T16:30:33.493 に答える