Descriptors
  jss 2011-07-07
What can you do
inside a class suite?
@c_decorator1
              @c_decorator0(foo=23)
              class Foo(object):
                  __metaclass__ = MetaClass
                  wenglo = 0
                  garply, corge = mktuple(qux)
                  @staticmethod
                  def fred(): pass
                  def __new__(klass): pass

All In One:       @classmethod
                  def wilma(klass): pass
                  def __init__(self, *_): pass
                  @f_decorator
                  def foo(self, *_): pass
                  @property
                  def bar(self): pass
                  @bar.setter
                  def set_bar(self, v): pass
                  helga = Descriptor()
                  print locals()
@c_decorator1
              @c_decorator0(foo=23)
              class Foo(object):
                  __metaclass__ = MetaClass
                  wenglo = 0
                  garply, corge = mktuple(qux)
                  @staticmethod
                  def fred(): pass
                  def __new__(klass): pass

All In One:       @classmethod
                  def wilma(klass): pass
                  def __init__(self, *_): pass
                  @f_decorator
                  def foo(self, *_): pass
                  @property
                  def bar(self): pass
                  @bar.setter
                  def set_bar(self, v): pass
                  helga = Descriptor()
                  print locals()
Descriptor Protocol

•   Descriptors are customized Object Attributes

•   An object with any of these defined is a descriptor:

     __get__(self, obj, type=None)

     __set__(self, obj, val)

     __delete__(self, obj)
Generic Descriptor Examples

class Foo(object):

    def wenglo(self):      f = Foo()
        return self.qux    f.wenglo()
    @classmethod           Foo.foo()
    def foo(klass):        Foo.wenglo()
        return klass.bar
    @staticmethod
      def buz():
          return 42
“Normal” attribute access

class Foo(object): pass

f = Foo()

f.bla

# implemented in object.__getattribute__:

== type(f).__dict__[‘bla’].__get__(f, type(f))
Demo


         show some code:

check out ListProperty in postamt.py
Implementing property()
# by Raymond Hettinger: http://users.rcn.com/python/download/Descriptor.htm
class property(object):
    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)

Descriptor Protocol

  • 1.
    Descriptors jss2011-07-07
  • 2.
    What can youdo inside a class suite?
  • 3.
    @c_decorator1 @c_decorator0(foo=23) class Foo(object): __metaclass__ = MetaClass wenglo = 0 garply, corge = mktuple(qux) @staticmethod def fred(): pass def __new__(klass): pass All In One: @classmethod def wilma(klass): pass def __init__(self, *_): pass @f_decorator def foo(self, *_): pass @property def bar(self): pass @bar.setter def set_bar(self, v): pass helga = Descriptor() print locals()
  • 4.
    @c_decorator1 @c_decorator0(foo=23) class Foo(object): __metaclass__ = MetaClass wenglo = 0 garply, corge = mktuple(qux) @staticmethod def fred(): pass def __new__(klass): pass All In One: @classmethod def wilma(klass): pass def __init__(self, *_): pass @f_decorator def foo(self, *_): pass @property def bar(self): pass @bar.setter def set_bar(self, v): pass helga = Descriptor() print locals()
  • 5.
    Descriptor Protocol • Descriptors are customized Object Attributes • An object with any of these defined is a descriptor: __get__(self, obj, type=None) __set__(self, obj, val) __delete__(self, obj)
  • 6.
    Generic Descriptor Examples classFoo(object): def wenglo(self): f = Foo() return self.qux f.wenglo() @classmethod Foo.foo() def foo(klass): Foo.wenglo() return klass.bar @staticmethod def buz(): return 42
  • 7.
    “Normal” attribute access classFoo(object): pass f = Foo() f.bla # implemented in object.__getattribute__: == type(f).__dict__[‘bla’].__get__(f, type(f))
  • 8.
    Demo show some code: check out ListProperty in postamt.py
  • 9.
    Implementing property() # byRaymond Hettinger: http://users.rcn.com/python/download/Descriptor.htm class property(object): 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)