マネージ属性がクラス属性に対してのみ機能し、Pythonのインスタンス属性に対して機能しないのはなぜですか?
-
06-07-2019 - |
質問
質問を説明するには、次のコードを確認してください:
class MyDescriptor(object):
def __get__(self, obj, type=None):
print "get", self, obj, type
return self._v
def __set__(self, obj, value):
self._v = value
print "set", self, obj, value
return None
class SomeClass1(object):
m = MyDescriptor()
class SomeClass2(object):
def __init__(self):
self.m = MyDescriptor()
x1 = SomeClass1()
x2 = SomeClass2()
x1.m = 1000
# -> set <__main__.MyDescriptor object at 0xb787c7ec> <__main__.SomeClass1 object at 0xb787cc8c> 10000
x2.m = 1000 # I guess that this overwrites the function. But why?
# ->
print x1.m
# -> get <__main__.MyDescriptor object at 0xb787c7ec> <__main__.SomeClass1 object at 0xb787cc8c> <class '__main__.SomeClass1'> 10000
print x2.m
# -> 10000
- x2.m = 1000 が __ set __ 関数を呼び出さないのはなぜですか?これは関数を上書きするようです。しかし、なぜですか?
- x1の _v はどこにありますか? x1._v にはありません
解決
2番目の質問に答えるには、 _v
はどこにありますか?
記述子のバージョンは、記述子自体に _v
を保持します。記述子の各インスタンス(クラスレベルインスタンス SomeClass1
、およびクラス SomeClass2
のオブジェクト内のすべてのオブジェクトレベルインスタンスには、 _v
。
このバージョンをご覧ください。このバージョンは、記述子に関連付けられたオブジェクトを更新します。これは、オブジェクト( SomeClass1
または x2
)に属性 _v
が含まれることを意味します。
class MyDescriptor(object):
def __get__(self, obj, type=None):
print "get", self, obj, type
return obj._v
def __set__(self, obj, value):
obj._v = value
print "set", self, obj, value
他のヒント
x1 の _v が見つかりました: SomeClass1 .__ dict __ ['m'] ._ v
にありますS.Lottが他の回答内で提案したバージョンの場合: _v は x1._v
にあります所属していません StackOverflow