Implicit Python Properties

Everybody knows that nice property function that uses the python descriptor protocol to call functions when getting or settings values. But the disadvantage: For read/write properties it requires two helper functions which causes code that looks like this:

class Foo(object):

    def __init__(self, initial):
        self.foo = initial

    def _get_foo(self):
        return self._foo

    def _set_foo(self, value):
        self._foo = value

    foo = property(_get_foo, _set_foo, 'The docstring')
    del _get_foo, _set_foo

I thought about introspecting the call frame and retrieving wrapped functions but because the python bytecode uses STORE_FAST/LOAD_FAST opcodes this doesn’t work. But with a little bit of bytecode hacking I got a decorator working that is both magical and implicit (and quite slow on application startup, but equally fast at execution because it just creates a normal property). It looks like this when in use:

class Foo(object):

    def __init__(self, initial):
        self.foo = initial

    @autoproperty
    def foo():
        '''The docstring'''
        def fget(self):
            return self._foo
        def fset(self, value):
            self._foo = value

The module that implements this decorator is available here: autoproperty.py

It’s cool to see what’s possible with python, even if it makes no sense and nobody would ever use it :D

One Response to “Implicit Python Properties”

  1. Interesting post. I use other code, but it don’t work with lambda’s :

    def mkprop(func):
        gfunc = sfunc = dfunc = None
        for i in func.func_code.co_consts:
            if isinstance(i,types.CodeType):
                if i.co_name == 'get':
                    gfunc = new.function(i,globals())
                elif i.co_name == 'set':
                    sfunc = new.function(i,globals())
                elif i.co_name == 'set':
                    sfunc = new.function(i,globals())
        if not gfunc and not sfunc and not dfunc:
            raise ValueError("Can't found and function to make property")
        else:
            return property(fget = gfunc,fset = sfunc,
                            fdel = dfunc,doc = func.__doc__)
    class Test(object):
        @mkprop
        def prop():
            "property"
            def set(self,val):
                self._val = val
            def get(self):
                return self._val
        #but not like this
        #def prop():
        #    get = lambda self : self._val
        #    set = my_other_function

    > It’s cool to see what’s possible with python, even if it makes no sense and nobody would
    > ever use it :D

    I’m gonna use it, instead o my one’s ;).
    P.S. +1 on Python cool.

    Comment by koder — Monday, June 11th, 2007 @ 3:01 pm

Leave a Reply

cogitations driven by wordpress