[Python-Dev] Definining properties - a use case for class decorators?
Nick Coghlan
ncoghlan at iinet.net.au
Sun Oct 16 15:56:10 CEST 2005
On and off, I've been looking for an elegant way to handle properties using
decorators.
It hasn't really worked, because decorators are inherently single function,
and properties span multiple functions.
However, it occurred to me that Python already contains a construct for
grouping multiple related functions together: classes.
And that thought led me to this decorator:
def def_property(cls_func):
cls = cls_func()
try:
fget = cls.get.im_func
except AttributeError:
fget = None
try:
fset = cls.set.im_func
except AttributeError:
fset = None
try:
fdel = cls.delete.im_func
except AttributeError:
fdel = None
return property(fget, fset, fdel, cls.__doc__)
Obviously, this decorator can only be used by decorating a function that
returns the class of interest:
class Demo(object):
@def_property
def test():
class prop:
"""This is a test property"""
def get(self):
print "Getting attribute on instance"
def set(self, value):
print "Setting attribute on instance"
def delete(self):
print "Deleting attribute on instance"
return prop
Which gives the following behaviour:
Py> Demo.test
<property object at 0x00B9CC38>
Py> Demo().test
Getting attribute on instance
Py> Demo().test = 1
Setting attribute on instance
Py> del Demo().test
Deleting attribute on instance
Py> help(Demo.test)
Help on property:
This is a test property
<get> = get(self)
<set> = set(self, value)
<delete> = delete(self)
If we had class decorators, though, the decorator could be modified to skip
the function invocation:
def def_property(cls):
try:
fget = cls.get.im_func
except AttributeError:
fget = None
try:
fset = cls.set.im_func
except AttributeError:
fset = None
try:
fdel = cls.delete.im_func
except AttributeError:
fdel = None
return property(fget, fset, fdel, cls.__doc__)
And the usage would be much more direct:
class Demo(object):
@def_property
class test:
"""This is a test property"""
def get(self):
print "Getting attribute on instance"
def set(self, value):
print "Setting attribute on instance"
def delete(self):
print "Deleting attribute on instance"
Comments? Screams of horror?
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.blogspot.com
More information about the Python-Dev
mailing list