property
オブジェクトは記述子です。記述子は、クラスにバインドされている場合にのみ特別な権限を持ちます。それ以外の場合は、他のクラスとまったく同じように動作します。プロパティをリストに入れると、クラスにバインドされないため、その特別なプロパティが失われます。
例として、記述子としてproperty
純粋な pythonで記述された の実装を見てみましょう。
class Property(object):
"Emulate PyProperty_Type() in Objects/descrobject.c"
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
self.fget = fget
self.fset = fset
self.fdel = fdel
self.__doc__ = doc
def __get__(self, obj, objtype=None):
if obj is None:
return self
if self.fget is None:
raise AttributeError, "unreadable attribute"
return self.fget(obj)
def __set__(self, obj, value):
if self.fset is None:
raise AttributeError, "can't set attribute"
self.fset(obj, value)
def __delete__(self, obj):
if self.fdel is None:
raise AttributeError, "can't delete attribute"
self.fdel(obj)
との 2 番目の引数が obj __get__
であることに注意してください。記述子がバインドされているクラスのインスタンスです (物事を明確にするのに役立つかのようにメソッドに渡されます)。シバン全体が機能するためには、記述子をクラスにバインドして、呼び出して渡すことができるようにする必要があります。記述子がクラスにバインドされていない場合、 は呼び出されず、記述子クラスは、(明示的に呼び出さない限り) 決して呼び出されないいくつかの魔法のメソッドを持つ単なる別のクラスになります。__set__
__delete__
obj
self
__get__
obj
__get__
もう少し具体的に言うと、次のようになります。
a = instance.my_descriptor
これはmy_descriptor.__get__(instance)
、それに応じて次のように呼び出します。
instance.my_descriptor = a
通話my_descriptor.__set__(instance,a)
ただし、my_descriptor
クラスにバインドされていない場合は、表示内容を説明する他のクラス (オブジェクト) と同じように動作します。