2012-04-22 18 views
14

ありません。私のコードではさらに上のPythonのクラスの継承:はAttributeError:「[サブクラス]」オブジェクトは、私は、次の基本クラスとサブクラス持って何の属性「XXX」

class Event(object): 
    def __init__(self, sr1=None, nr1=None, foo=None, foobar=None, nr2=None, sr2=None, flag = False): 
     self.sr1 = sr1 
     self.nr1 = nr1 
     self.foo = foo 
     self.foobar = foobar 
     self.nr2 = nr2 
     self.sr2 = sr2 
     self.flag = flag 
     self.state = STATE_NON_EVENT 

    def state_name(self): 
     return STATE_NAMES[self.state] 

    def __repr__(self): 
     return '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 

    def __repr__(self): 
     return "Type Two event (Level @: {0:.2f})".format(self.sr1) 

を、私はのインスタンスを検査していますTypeTwoEventクラスは、私が知っているフィールドが基本クラスに存在するかどうかをチェックしています。値がNoneにデフォルト設定されていると思いました。しかし、私のコードは次の例外を発生させます:

AttributeError: 'TypeTwoEvent' object has no attribute 'foobar'

私は、基本クラスのフィールドはサブクラスによって、ベースクラスをインスタンス化しますサブクラスのインスタンスを作成することを継承されるだろうという印象の下にあった(したがって、そのコンストラクタを呼び出す)...

私はここで何が欠けていますか? TypeTwoEventにfoobar属性がないのはなぜですか?それが由来する基底クラスにはfoobar属性がありますか?

+1

以下に述べるように、スーパークラスを初期化することを明示する必要があります。しかし、__ take care__:複数の継承がある場合、これは非常に繊細になります。 – katrielalex

答えて

15

あなたのサブクラスでは、次のようになります。

class TypeTwoEvent(Event): 

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

    def __repr__(self): 
     return "Type Two event (Level @: {0:.2f})".format(self.sr1) 

あなたが__init__メソッドをオーバーライドするので、あなたは親の行動が起こるしたい場合は、親メソッドを呼び出す必要がありますので。

__init__は、その奇妙な名前を派遣する特別な方法ではありません。これは、オブジェクトの作成後に自動的に呼び出されるメソッドです。それ以外の場合は通常の方法で、通常の継承規則が適用されます。

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

は、メソッドの親バージョンを呼び出す構文です。 *args**kwargsについては

、それはちょうど私達が__init__に渡されたすべての追加の引数をキャッチし、あなたの子メソッドのシグネチャはそれをしなかったと親がこれらの引数は、作業する必要があるとして、親メソッドに渡し保証します。

+0

クリスを編集してくれてありがとう。私はフランス人です、そして、私はこの "it's"と "its"の間の混乱をかなり頻繁にします。私は意味を混ぜるのではなく、言葉を話すことを学んだので、私の頭の中で別のものの音を交換するのは簡単です(:-))。 –

1

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

これを行う方法はhereを参照してください。

2

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

あなたはTypeTwoEvent.__init__からEvent.__init__(self, ...)を呼び出す(またはsuperを使用しますが、あなたはそれに慣れていない場合は、何をやっている知っているので、まずそれをよく読んで)必要があります。

2

親クラスのコンストラクタ(__init__)をオーバーライドしています。それを拡張するには、super()呼び出しで親のコンストラクターを明示的に呼び出す必要があります。 superコールがあなたのサブクラスで__init__メソッドの上部に常にではないことを

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 

注意。その場所はあなたの状況とロジックによって異なります。

0

私もこれに問題がありましたが、私はsuper().__init__()を派生クラスの底に置いています。そのため、動作しません。私は初期化されていない属性を使用しようとしているからです。

関連する問題