Descriptors
Table of Contents
Overview
descr.__get__(self, obj, type=None) # -> value
descr.__set__(self, obj, value) # -> None
descr.__delete__(self, obj) # -> Nonefrom weakref import WeakKeyDictionary
class Grade(object):
def __init__(self):
self._values = WeakKeyDictionary()
def __get__(self, instance, instance_type):
if instance is None:
return self
else:
return self._values.get(instance, 0)
def __set__(self, instance, value):
# Do something special
self._values[instance] = value- Descriptors are invoked by the
__getattribute__()method - Overriding
__getattribute__()prevents automatic descriptor calls __getattribute__()is only available with new style classes and objectsobject.__getattribute__()andtype.__getattribute__()make different calls to__get__().
Functions and Methods discussion
For classes, method definitions are just functions. For instances, these functions need to be bound to the instance. To support method calls, functions include the __get__() method for binding methods during attribute access.
class Function(object):
. . .
def __get__(self, obj, objtype=None):
"Simulate func_descr_get() in Objects/funcobject.c"
return types.MethodType(self, obj, objtype)Data descriptors vs. non-data descriptors discussion
- Data descriptor: defines both
__get__()and__set__() - Non-data descriptor: defines only
__get__()
- Data descriptors always override instance dictionaries.
- Non-data descriptors may be overridden by instance dictionaries.
- Following example shows that data descriptor(
@property) takes precedence over non-data descriptor(Descriptor)
>>> class Descriptor(object):
... def __init__(self, name):
... self.name = name
... def __get__(self, instance, cls):
... print 'Getting %s, with instance %r, class %r' % (self.name, instance, cls)
...
>>> class Foo(object):
... _spam = 'eggs'
... @property
... def spam(self):
... return self._spam
... @spam.setter
... def spam(self, val):
... self._spam = val
...
>>> Foo().spam
'eggs'
>>> foo = Foo()
>>> foo.__dict__['spam'] = Descriptor('Override')
>>> foo.spam
'eggs'