ドキュメントから。
オブジェクトの場合、機械は にobject.__getattribute__()
変換b.x
されtype(b).__dict__['x'].__get__(b, type(b))
ます。
つまり、インスタンス( ) の属性検索は、クラス( )b
の記述子呼び出しに変換されます。記述子は、クラス レベルで動作します。type(b)
なぜこれが正しいのかというと、記述子は基本的に、属性ルックアップでメソッドのような作業 (つまり、メソッドを呼び出す) を行う方法だからです。また、メソッドは基本的にクラス レベルの動作です。一般に、クラスで必要なメソッドを定義し、個々のインスタンスに余分なメソッドを追加しません。インスタンスで記述子ルックアップを行うことは、インスタンスでメソッドを定義するようなものです。
現在、インスタンスに新しいメソッドを割り当てることが可能であり、特定のクラスのインスタンスで機能する記述子を取得することも可能です。余分な作業を行うだけです。上記のドキュメントの引用にあるように、機械は にあるため、クラスobject.__getattribute__
にカスタムを定義することでオーバーライドできます。__getattribute__
class Foo(object):
def __getattribute__(self, attr):
myDict = object.__getattribute__(self, '__dict__')
if attr in myDict and hasattr(myDict[attr], '__get__'):
return myDict[attr].__get__(self, type(self))
else:
return super(Foo, self).__getattribute__(attr)
class D(object):
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
pass
def __get__(self, obj, objtype=None):
return 5
その後:
>>> f = Foo()
>>> f.x = D()
>>> f.x
5
したがって、これを行う必要があると感じた場合は、それを実現できます。これは、記述子が設計されたものではないという理由だけで、デフォルトの動作ではありません。