2016-09-26 13 views
3

__set__と記述子を持つことができ、__get__を使用できないという事実について、どこかで読んでいます。__set__ではなく__get__ではない記述子はどのように機能しますか?

どのように動作しますか?

データディスクリプタとしてカウントされますか?それは非データ記述子ですか?ここで

はコードの例です:あなたが例に与えてくれた

class Desc: 
    def __init__(self, name): 
     self.name = name 
    def __set__(self, inst, value): 
     inst.__dict__[self.name] = value 
     print("set", self.name) 

class Test: 
    attr = Desc("attr") 

>>>myinst = Test() 
>>> myinst.attr = 1234 
set attr 
>>> myinst.attr 
1234 
>>> myinst.attr = 5678 
set attr 
>>> myinst.attr 
5678 

答えて

5

記述子は、データ記述子です。

は、他のデータ記述子として、属性を設定したら、それは最高の優先度を取り、そのように呼ばれている:順番に

type(myinst).__dict__["attr"].__set__(myinst, 1234) 

これは、あなたの__set__方法に従ってインスタンス辞書にattrを追加します。属性アクセスの際

は、記述子は__get__メソッドを持つためにチェックしたが失敗し、そのようなインスタンスの辞書にリダイレクトするための検索のために引き起こしている:

myinst.__dict__["attr"] 

それはインスタンス辞書で見つからない場合、記述子自体が返されます。

この動作はすぐにそうようdata modelに記載されています:

それは オブジェクトのインスタンス辞書に値がある場合を除き、その後 記述子オブジェクト自体を返します属性にアクセスし、__get__()を定義していない場合。

一般的な用途には、デスクリプタ内に{instance: value}辞書を避け、値を効率的にキャッシュします。


は、Python 3.6で、__set_name__は、このように記述内部名を指定するための必要性を排除するディスクリプタプロトコルに加えました。このようにして、あなたの記述子は次のように書くことができます:

class Desc: 
    def __set_name__(self, owner, name): 
     self.name = name 
    def __set__(self, inst, value): 
     inst.__dict__[self.name] = value 
     print("set", self.name) 

class Test: 
    attr = Desc() 
+0

データモデルに記載されている動作については、Raymondの[how to](https://docs.python.org/2/)に詳しい説明があります。 howto/descriptor.html)ガイドを参照してください。 – wim

+0

@wim実際、この質問を最初に提起した理由は、そこには記載されていないからです。 '__get__'のないデータ記述子は何もありません。それがどのように動作するかを理解するために私をしばらく時間がかかりました。私はそれを自分自身のpydocsに追加します。 – Bharel

関連する問題