1

可変メソッド名を使用してスーパークラスのメソッドを呼び出そうとしています。通常、次の 2 行のコードは同等のものとして表示されます。

someObj.method()
someObj.__getattribute__( 'method' )()

実際、これは最初の行を使用したときに実際に起こることでもあると私は信じています。ただし、次の例では、2 行目で奇妙な問題が発生します。

superスーパー オブジェクトを構築し、スーパー クラスのメソッドを呼び出すために使用します。直接実行すると期待どおりに機能し__getattribute__ますが、最初にメソッドを取得するために使用すると、サブクラスのメソッドを何度も呼び出す無限ループが発生します。

次のコードを参照してください。

class A:
    def example ( self ):
        print( 'example in A' )

class B ( A ):
    def example ( self ):
        print( super( B, self ).example )
        print( super( B, self ).__getattribute__( 'example' ) )
        super( B, self ).example()
        #super( B, self ).__getattribute__( 'example' )()

        print( 'example in B' )

x = B()
x.example()

そのコードを実行すると、すべてが期待どおりに機能し、次のような出力が得られるはずです。

<bound method B.example of <__main__.B object at 0x01CF6C90>>
<bound method B.example of <__main__.B object at 0x01CF6C90>>
example in A
example in B

したがって、直接アクセスする方法と を介する方法の両方の方法は__getattribute__同じように見えます。ただし、メソッド呼び出しをコメントアウトされた行に置き換えると、再帰ランタイム エラーが発生します。

なぜこれが起こるのか、さらに重要なことに、作業ラインを使用するときに、Python が内部的に行うのと同じ方法で実際にメソッドにアクセスするにはどうすればよいでしょうか?

編集

すでにすべてを試したと思ったとき、これが機能していることがわかりました:

super.__getattribute__( super( B, self ), 'example' )()

実際には に等しくなりsuper( B, self ).exampleます。

4

2 に答える 2

5

これには使用しない__getattribute__でください。あなたが思っていることをしません。(これは Python の機構の特殊な部分であり、主に新しい属性アクセス マジックを実装する場合に使用します。)

通常の属性アクセスには、 // ビルトインを使用getattrsetattrますdelattr:

self.example           == getattr(self, 'example')
super(B, self).example == getattr(super(B, self), 'example')

(何が機能するかを理解したい場合__getattribute__は、Descriptor ハウツー ガイドと Pythonデータ モデルリファレンスをお読みください。)

于 2010-10-03T02:21:09.447 に答える
0

exampleオブジェクトの属性を取得するBと、 のバインドされたコピーが生成されますB.example。これを呼び出すと、再帰エラーが発生します。あなたが呼ぶことA.__getattribute__()は関係ありません。あなたはまだBオブジェクトを持っています。

于 2010-10-02T23:31:43.360 に答える