挙動

2012-02-13 10 views
5
In [5]: class a(object): 
    ...:  def __init__(self): 
    ...:   print "In class a" 
    ...:   self.a = 1 
    ...:   
In [6]: class b(object): 
    ...:  def __init__(self): 
    ...:   print "In class b" 
    ...:   self.b = 2 
    ...:   
    ...:   

In [7]: class c(b, a): 
    ...:  pass 
    ...: 
In [8]: c.mro() 
Out[8]: 
[<class '__main__.c'>, 
<class '__main__.b'>, 
<class '__main__.a'>, 
<type 'object'>] 

In [9]: obj = c() 
In class b 

In [10]: obj.__dict__ 
Out[10]: {'b': 2} 

デフォルト__init__方法は、内部でのみクラスb__init__を呼び出すobj作成、上と呼ばれています。挙動

2クラスから継承すると、派生したクラスオブジェクトは両方のクラスの変数を持つ必要があります(それらのクラスに対してプライベートでない限り)。

私の質問:派生オブジェクトに両方のクラスの変数が含まれていると誤っていますか?もしそうなら、なぜですか?クラスa__init__も呼ばれてはいけませんか? C++のような言語で何が起こったでしょうか?

+0

jcolladoの回答が正しいです。 'super'の仕組みの詳細については、[この回答](http://stackoverflow.com/q/607186)を参照してください。 – perelman

答えて

8

Pythonでは、上位クラスからの初期化メソッドはデフォルトで呼び出されません。

class a(object): 
    def __init__(self): 
     super(a, self).__init__() 
     print "In class a" 
     self.a = 1 

class b(object): 
    def __init__(self): 
     super(b, self).__init__() 
     print "In class b" 
     self.b = 2 

class c(b, a): 
    pass 

obj = c() 

出力例を:これを行うには、明示的に次のようにsuperを使用してそれらを呼び出す必要があります。クラスで

クラスBでは

編集:これは、このように動作する理由については、私はそれがThe Zen of of Pythonに基づいて設計上の決定だと言うだろうが:

明示されます暗黙的よりも優れています。

+0

なぜ 'super(b、self).__ init __()'はaの '__init__'メソッドを呼び出しますか?aはbのスーパークラスではありません。 – avasal

+0

@avasal、yes 'super'呼び出しは、mroシーケンスで次に利用可能なメソッドを見つけます。与えられたコードは 'object .__ init__'が存在し、引数なしで呼び出されるため、このコードが有効であることに注意してください。クラス内の' __init__'が引数を取った場合、または別のメソッドを宣言したい場合、終了するために介在するスタブクラスが必要な場合があります'super'コールの連鎖。 http://rhettinger.wordpress.com/2011/05/26/super-considered-super/も参照してください。 – Duncan