1

getattr メソッドをオーバーライドしようとしていますが、私の理解では、次のコード スニペットに無限ループが存在するはずです。デフォルトでは object.__getattribute__(self,attr)が呼び出され、属性 'notpresent' が存在しないため、オーバーライドされた getattr メソッドが呼び出されます。名前空間とこのプロセスが繰り返されます。ここでこの動作が観察されない理由を理解するのを手伝ってくれる人はいますか。

さらに、メソッド内で getattribute を明示的に呼び出そうとしたときに、ドット表記を使用して属性にアクセスしているときに getattribute への暗黙的な呼び出しが行われたときに AttributeError が発生しない理由を理解できません。

class Test(object):

    #Act as a fallback and is invoked when getattribute is unable to find attribute

    def __getattr__(self,attr):

        print "getattr is called"
        return object.__getattribute__(self,attr) #AttributeError is raised

t=Test([1,2,3,4])

b = t.notpresent
4

2 に答える 2

4

object.__getattribute__内で呼び出していますTest.__getattr__

ここにはループは含まれていません。

さらに、 docsに従って、__getattribute__暗黙的に を呼び出しません__getattr__

編集後に更新

呼び出しの C 実装を次に示します__getattribute__。特にそのslot_tp_getattr_hook部分。

__getattr__あなたの場合、属性ルックアップの失敗により、カスタム関数を呼び出す6072行目が実行されます。

そこから、AttributeErrorはクリアされました。しかし、あなたの呼び出しobject.__getattribute__はそれを元に戻し、6074 行目または 6075 行目はそれを処理しません。

呼び出しはそのobject.__getattribute__ように実装されているため、(再)レイズしますAttributeError(1107 行目)。

于 2015-07-21T08:36:37.287 に答える
0

__getattribute__通常__dict__、オブジェクトの および同様の場所で属性を検索するだけなので、属性を取得するために暗黙的に呼び出すことはありません__getattr__

属性の検索に失敗した場合、メソッド__getattribute__を呼び出す場合__getattr____getattr__メソッドが 2 回呼び出される可能性があることに注意してください(ルックアップは失敗時に呼び出されることになっているため)。__getattribute____getattr____getattribute__

于 2015-07-21T08:39:48.163 に答える