inherit and overwrite a property (better its method call)

Nicodemus nicodemus at esss.com.br
Sun Feb 29 20:55:54 EST 2004


Peter Otten wrote:

>chris wrote:
><snip>
>http://www.python.org/2.2/descrintro.html might also be of interest for you.
>It has an example of properties based on naming conventions (class
>autoprop).
>
>  
>

I ran into the same problem, and coded a property of my own. The problem 
is that property() holds the actual functions, so when you overwrite 
them in the subclass, the property doesn't know about it. The approach 
below only saves the name of the function, and delays the lookup of the 
actual function when needed.


class subclass_property(object):
    '''Creates an property just like a built-in property, except that the
    functions that are part of the property can be changed in a subclass.
    '''

    def __init__(self, fget=None, fset=None, fdel=None, doc=None):
        self.fget_name = fget and fget.__name__
        self.fset_name = fset and fset.__name__
        if isinstance(fdel, str):
            doc = fdel
            fdel = None
        self.fdel_name = fdel and fdel.__name__
        self.doc = doc or '' 


    def __get__(self, obj, objtype=None):
        if obj is None:
            return self        
        if self.fget_name is None:
            raise AttributeError, "unreadable attribute"
        fget = getattr(obj, self.fget_name)
        return fget()
   

    def __set__(self, obj, value):
        if self.fset_name is None:
            raise AttributeError, "can't set attribute"
        fset = getattr(obj, self.fset_name)
        fset(value)


    def __delete__(self, obj):
        if self.fdel_name is None:
            raise AttributeError, "can't delete attribute"
        fdel = getattr(obj, self.fdel_name)
        fdel()


    def __repr__(self):
        p = []
        if self.fget_name:
            p.append(self.fget_name)
        if self.fset_name:
            p.append(self.fset_name)
        if self.fdel_name:
            p.append(self.fdel_name)
        if self.doc:
            p.append(repr(self.doc))
        return 'action.property(%s)' % ', '.join(p)



HTH,
Nicodemus.





More information about the Python-list mailing list