Saturday, July 26, 2014

Python descriptor example

A descriptor in python is a “binding behavior” for data accessing and manipulation. An example from python’s official documentation (Descriptor HowTo Guide — Python v2.7.8 documentation):

class RevealAccess(object):
    """A data descriptor that sets and returns values
       normally and prints a message logging their access.

    def __init__(self, initval=None, name='var'):
        self.val = initval = name

    def __get__(self, obj, objtype):
        print("obj: \n", obj)
        print("objtype: \n", objtype)
        print 'Retrieving',
        return self.val

    def __set__(self, obj, val):
        print("obj: \n", obj)
        print("val: \n", val)
        print 'Updating',
        self.val = val

class MyClass(object):
    x = RevealAccess(10, 'var "x"')
    y = 5

m = MyClass()
# Retrieving var "x"
# 10
m.x = 20
# Updating var "x"
# Retrieving var "x"
# 20
# 5

Here MyClass contains a member x, which in turn is an instance of the class RevealAccess. Normally, when you access x by m.x, you should get the object x itself, but since x has the __get__ member function, python will return to you the result of m.x.__get__() instead. And similarly, when you assign a value, i.e. m.x = 20, python will call m.x.__set__(20).

Note that in def __get__(self, obj, objtype), obj is actually m, and objtype is MyClass, you don’t need to specify these.