1. beautiful_life

    Posted

    beautiful_life
Changes in title
+pythonのディスクリプター
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,61 @@
+ディスクリプターとは下記のようなメソッドを備えたクラスのことである。
+
+|メソッド|呼び出しタイミング|
+|---|---|
+|__get__(self,obj,type)|アトリビュートを取得するとき|
+|__set__(self,obj,value)|アトリビュートを設定するとき|
+|__delete__(self,obj)|アトリビュートを削除するとき|
+
+
+__getattr__, __setattr__などの特殊メソッドとは異なるメソッドであるため、ディスクリプターとは区別して認識する必要がある。
+
+・アトリビュート操作に関わる挙動を別クラスに切り出せる(=クラスをまたがるアトリビュート関連の機能を再利用できる。)
+・特定のアトリビュートに対してのみ適用される挙動を定義できる。(__getattr__, __setattr__では、そのクラスのすべてのアトリビュートに影響)
+
+な丼メリットがあります。ディスクリプターは、プロパティをはじめ、クラス/静的メソッド、superなどの背後でも利用されています。
+
+
+
+```descriptor_basic.py
+#ディスクリプターの定義
+class LogProp:
+ def __init__(self,name): #1
+ self.name = name #1
+
+ #アトリビュートを取得するときの処理
+ def __get__(self,obj,type): #2
+ prin(f'{self.name}:get') #2,6
+ return obj.__dict__[self.name] #2,4
+
+ #アトリビュートを設定するときの処理
+ def __set__(self,obj,value) #3
+ prin(f'{self.name}:set{value}') #3,7
+ obj.__dict__[self.name] = value #3,5
+
+class App:
+ #ディスクリプターの定義
+ title = LogProp('title') #8
+
+if __name__ == '__main__':
+ app = App()
+ app.title = '独習Python' #9
+ print(app.title) #9
+````
+ディスクリプターの側で定義しているのは、__init__, __get__, __set__です。まず、__init__メソッド(#1)は、ディスクリプターの対象となるアトリビュート名を受け取り、これを保存しています。後で値を受け渡しするためのキーとなる情報です。
+
+そして、__set__(#2), __get__(#3)が値受け渡しのための主となるメソッドです。__get__, __set__は、引数経由で以下の情報を受け取ります。
+
+obj:対象となるインスタンス
+type:対象となるクラス
+value:渡された値
+
+この例であれば、__dict__を介してインスタンスの値を取得、参照しています。__get__, __set__はインスタンスのアトリビュート操作を肩代わりするので、なんらかの値の取得、保存操作が無い場合アトリビュート値の取得、設定は無効になります。
+
+コード中の#4,5のような記述を最低限とし、取得、設定時の追加的な操作を加えておきましょう。この例であれば、取得、設定の結果をprintで出力しています。
+
+定義済みのディスクリプターをアトリビュートに紐づけるには、#8のようにします。(これはproperty関数でプロパティを定義するのと同じ書き方です。)
+
+コード中の#9のようにtitleを設定・sy津億したタイミングでログが出力されることが確認できます。
+
+
+独習python 第11章オブジェクト指向構文 より引用