ディスクリプタとは
特殊メソッド__get__、__set__、__delete__のうちいずれかのメソッドが定義されたオブジェクトをディスクリプタと呼びます。ディスクリプタをメンバにもつオブジェクトに対し、そのメンバにアクセスしたときの挙動をカスタマイズすることが可能となります。ディスクリプタそのものに対するアクセス時に__get__、__set__、__delete__が実行されるわけではない点に注意してください。
まずはサンプルとしてディスクリプタを実装したサンプルを紹介します。以下のコードでは、属性textをもったクラスMyDescriptorにディスクリプタを実装しています。参照、更新、削除した際の挙動がカスタマイズされています。
class MyDescriptor:
""" ディスクリプタクラス """
def __init__(self, text):
self.text = text
def __get__(self, instance, owner):
return "* " + self.text
def __set__(self, instance, text):
self.text = text + "!"
def __delete__(self, instance):
del self.text
print('text属性が削除されました')
class Sample:
""" 属性にディスクリプタを持つ """
descriptor = MyDescriptor('sample')
obj = Sample()
print(obj.descriptor) # * sample
obj.descriptor = 'sample2'
print(obj.descriptor) # * sample2!
del obj.descriptor # text属性が削除されました
print(obj.descriptor) # AttributeError
ディスクリプタのメソッド
ではここから先程のサンプルを上から順に解説していきます。
__get__
メンバを参照した際の挙動を定義します。上のサンプルでは、Sampleクラスのdescriptorメンバにアクセスした際に__get__が呼び出されています。このことにより、アクセスした結果に対し、先頭に*が付加されるようになっています。
__set__
メンバを更新した際の挙動を定義します。上のサンプルでは、Sampleクラスのdescriptorメンバを更新した際に__set__が呼び出されています。このことにより、設定した内容に対し、末尾に!が付加されるようになっています。
__delete__
メンバを削除した際の挙動を定義します。上のサンプルでは、Sampleクラスのdescriptorメンバを削除した際に__delete__が呼び出されています。このことにより、削除時にメッセージが表示されるようになっています。
