Skip to content

Instantly share code, notes, and snippets.

@FGtatsuro
Created July 10, 2018 00:10
Show Gist options
  • Save FGtatsuro/cc2f34fb9efe62b4fa7017f1b4b7eb2d to your computer and use it in GitHub Desktop.
Save FGtatsuro/cc2f34fb9efe62b4fa7017f1b4b7eb2d to your computer and use it in GitHub Desktop.
デスクリプタにアクセスする際に渡される情報
class Desp:
def __get__(self, instance, owner):
# self: デスクリプタ
# instance: デスクリプタを属性として持つインスタンス
# owner: デスクリプタを属性として持つクラス
print(f'__get__self:{self}')
print(f'__get__instance:{instance}')
print(f'__get__owner:{owner}')
# instance=None(クラス経由でのアクセス)でデスクリプタ自身を返すのはpropertyの実装であり、
# 強制されるものではない。
# FYI: https://docs.python.jp/3/howto/descriptor.html#properties
# FYI: https://qiita.com/knzm/items/a8a0fead6e1706663c22#%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3%E3%81%AE%E5%A0%B4%E5%90%88
if not instance:
return self
# ただしraiseするのはAttributeErrorのみ
# FYI: https://docs.python.jp/3/reference/datamodel.html#object.__get__
# instance=Noneならば、getattr(instance, self._name)はAttributeErrorをraiseするため、
# 特に追加のコードはいらない。
# デスクリプタ自体ではなく、デスクリプタを属性として持つインスタンスに値をセット。
# これにより異なるインスタンス間で値が共有されることがなくなる。
return getattr(instance, self._name)
def __set__(self, instance, value):
print(f'__set__self:{self}')
print(f'__set__instance:{instance}')
return setattr(instance, self._name, value)
def __set_name__(self, owner, name):
# name: ディスクリプタにアクセスするための属性名
print(f'__set_name__self:{self}')
print(f'__set_name__owner:{owner}')
print(f'__set_name__name:{name}')
self._name = f'_{name}'
class A:
des = Desp()
a1 = A()
a2 = A()
a1.des = 5
a2.des = 6
print(a1.des)
print(a2.des)
# クラス経由でデスクリプタ属性にアクセス。instanceはNoneになる。
print(A.des)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment