2011-10-22 32 views
10

このコードは例外をスローします。AttributeError、 "wtf!"A.foo()B.foo1()を呼び出しているため、A.foo1()を呼び出してはいけませんか?私はA.foo1()を呼び出すためにそれを強制することができますどのようにそれはプログラミング言語が動作し、世界の100%と、意図したとおりに機能さオーバーライドされたメソッドを呼び出すと、オーバーライドされた呼び出しメソッドのスーパークラス

class A(object): 
    def foo(self): 
     print self.foo1() 

    def foo1(self): 
     return "foo" 

class B(A): 
    def foo1(self): 
     raise AttributeError, "wtf!" 

    def foo(self): 
     raise AttributeError, "wtf!" 

    def foo2(self): 
     super(B, self).foo() 

myB = B() 
myB.foo2() 
+1

基本的には、Pythonが動的性や仮想的なメソッドを投げ捨てるように求めています。*関数が字句的に定義されている場所に基づいて、属性ルックアップチェーンの一部をスキップするようにしています。起こることはありません。 – delnan

答えて

5

(およびA.foo()内部の任意のメソッド呼び出しは、A.*を呼び出す必要があります)。サブクラスは親クラスのすべてのメソッドをオーバーライドします。

しかし、実際にA.foo1()を呼びたい場合は、このようにすることができます(保証できません)。そして、これは良いプログラミングのすべての原則に反しているので、あなたはこれをしてはいけません。コードで

class A(object): 

    def foo(self): 
     A.foo1(self) 
2

def foo2(self): 
    super(B, self).foo() 

自己Aから誘導される方法はBのインスタンスにより呼び出された場合B.

のインスタンスであることから、名前空間で検索を開始しますBであり、メソッドが見つからない場合(例えば、Bによってオーバーライドされていない場合)に限り、Aからの実装が使用されるが、常にBを自己参照する。自己はAのインスタンスである。

6

In selfメソッドを呼び出すのではなく、Aメソッドを呼び出してselfを手動で渡す必要があります。

これは通常のやり方ではありません。は本当にのような理由があります。

class A(object): 
    def foo(self): 
     print A.foo1(self) 

    def foo1(self): 
     return "foo" 

class B(A): 
    def foo1(self): 
     raise AttributeError, "wtf!" 

    def foo(self): 
     raise AttributeError, "wtf!" 

    def foo2(self): 
     super(B, self).foo() 

myB = B() 
myB.foo2() 
-1

ここでPythonが何をしているかを見ることができますが、上書きの方法は少し極端です。クラスAが100個の属性を定義し、クラスBがこれらを継承し、さらに1個の属性を追加する場合を考えてみましょう。 Bの__init __()にAの__init __()を呼び出し、Bのコードがその単一の属性だけを定義するようにしたいと考えています。同様に、Aでreset()メソッドを定義してすべての属性を0に設定した場合、Bの対応するreset()メソッドは、Aのreset()メソッドを呼び出して、代わりに単一のB属性をゼロにすることができますすべてのAコードを複製する必要があります。 Pythonは、オブジェクト指向プログラミングの大きなメリットとなるものを難しくしています。つまり、コードの再利用です。ここでの最良の選択肢は、私たちが本当に再利用したいメソッドのオーバーライドを避けることです。

class X(object): 
    def __init__ (self): 
     print "X" 
     self.x = 'x' 
     self.reset() 
     print "back to X" 
    def reset (self): 
     print "reset X" 
     self.xx = 'xx' 

class Y(X): 
    def __init__ (self): 
     print "Y" 
     super(Y,self).__init__() 
     self.y = 'y' 
     self.reset() 
     print "back to Y" 
    def reset (self): 
     print "reset Y" 
     super(Y,self).reset() 
     print "back to reset Y" 
     self.yy = 'yy' 

aY = Y() 

(クラスY.のための__init __でself.reset()()の呼び出しを削除し、適切にこの作業を行うには)

:あなたはここのPythonと合併症の感覚を取得したい場合は、このコードを試してみてください
関連する問題