Probably you have already discussed this topic, but maybe you can stand touching it again briefly. Maybe properties aren't used so often to deserve a specific syntax, but I don't like their syntax much. Here I show some alternative solutions that work with the current Python, followed by a syntax idea, that may be better fit for Python 3.0 (but maybe changing its name it can be retrofitted into Python 2.6 too).
Some code is from: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410698 That I have modified to suit my tastes. # The first version doesn't work with Psyco: # import psyco; psyco.full() import sys def nestedproperty(function): keys = '__get__', '__set__', '__del__' func_locals = {'doc':function.__doc__} def probe_function(frame, event, arg): if event == 'return': locals = frame.f_locals func_locals.update(dict((k, locals.get(k)) for k in keys)) sys.settrace(None) return probe_function sys.settrace(probe_function) function() return property(fget=func_locals.get("__get__"), fset=func_locals.get("__set__"), fdel=func_locals.get("__del__"), doc=func_locals.get("doc") ) class Angle(object): def __init__(self, rad): self._rad = rad @nestedproperty def rad(): "The angle in radians" def __get__(self): return self._rad def __set__(self, angle): if isinstance(angle, Angle): angle = angle.rad self._rad = float(angle) a = Angle(5) print a.rad a.rad = 10 print a.rad help(a) # ===================================================== # The second version is cleaner, but at the moment it has a problem with the property docstring (but that may be fixed) (it works with Psyco): class classpropertytype(property): "Pythonic property syntax." # Code from: # www.z3lab.org/sections/blogs/philipp-weitershausen/2006_05_29_pycon-06-lightning-talk/ def __init__(self, name, bases=(), members=None): if members is None: members = {} doc = members.get('__doc__') if doc is None: doc = members.get('__get__').__doc__ sup = super(classpropertytype, self) return sup.__init__(members.get('__get__'), members.get('__set__'), members.get('__del__'), doc) classproperty = classpropertytype('classproperty') class Angle(object): def __init__(self, rad): self._rad = rad class rad(classproperty): "The angle in radians" def __get__(self): return self._rad def __set__(self,angle): if isinstance(angle, Angle): angle = angle.rad self._rad = angle a = Angle(5) print a.rad a.rad = 10 print a.rad help(a) # ===================================================== # The third way has a bit of magic, but I like it best, and it works with Psyco too: class _property_meta(type): def __new__(meta, class_name, bases, new_attrs): if bases == (object,): # The property class itself return type.__new__(meta,class_name,bases,new_attrs) keys = "fget fset fdel __doc__".split() return property(*(new_attrs.get(k) for k in keys)) class classproperty(object): __metaclass__ = _property_meta def __new__(cls, fget=None, fset=None, fdel=None, fdoc=None): if fdoc is None and fget is not None: fdoc = fget.__doc__ return property(fget, fset, fdel, fdoc) class Angle(object): def __init__(self, rad): self._rad = rad class rad(classproperty): "The angle in radians" def fget(self): return self._rad def fset(self,angle): if isinstance(angle, Angle): angle = angle.rad self._rad = angle a = Angle(5) print a.rad a.rad = 10 print a.rad help(a) # ===================================================== # I may appreciate a better syntax, this is just an idea: # (George Sakkis has suggested a different syntax that I like less) """ class Angle(object): def __init__(self,rad): self._rad = rad property rad: "The angle in radians" def __get__(self): return self._rad def __set__(self, angle): if isinstance(angle, Angle): angle = angle.rad self._rad = angle class Angle2(Angle): property rad: def __get__(self): return self._rad * 2 """ # I'd like that possible syntax to mean this: class Angle(object): def __init__(self, rad): self._rad = rad def get_rad(self): return self._rad def set_rad(self, angle): if isinstance(angle, Angle): angle = angle.rad self._rad = angle rad = property(fget=lambda self: self.get_rad(), fset=lambda self, angle: self.set_rad(angle), doc="The angle in radians" ) class Angle2(Angle): def get_rad(self): return self._rad * 2 a = Angle(5) print a.rad a.rad = 10 print a.rad help(a) a = Angle2(5) print a.rad a.rad = 10 print a.rad help(a) Bye, bearophile -- http://mail.python.org/mailman/listinfo/python-list