マネージ属性がクラス属性に対してのみ機能し、Pythonのインスタンス属性に対して機能しないのはなぜですか?

StackOverflow https://stackoverflow.com/questions/428264

  •  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
  1. x2.m = 1000 __ set __ 関数を呼び出さないのはなぜですか?これは関数を上書きするようです。しかし、なぜですか?
  2. x1の _v はどこにありますか? x1._v
  3. にはありません
役に立ちましたか?

解決

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

他のヒント

これおよびこれ

SomeClassではなくMyDescriptorクラスの __ set __ および __ get __ 関数をオーバーロードしなかったため、関数を上書きします。 SomeClassがMyDescriptorを継承することを望んでいるかもしれません。 SomeClass1は「get」を出力します;および「設定」これは静的メソッドAFAIKであるため出力されます。詳細については、上のリンクをご覧ください。

x1 _v が見つかりました: SomeClass1 .__ dict __ ['m'] ._ v

にあります

S.Lottが他の回答内で提案したバージョンの場合: _v x1._v

にあります
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top