Welcome, guest | Sign In | My Account | Store | Cart
########## Solution I (Better) ##########
# Inspired by many other recipes in this cookbook.
class lazyproperty(object):
    def __init__(self, fget=None, fset=None, fdel=None, doc=''):
        for attr in ('fget', 'fset'):
            func = locals()[attr]
            if callable(func):
                setattr(self, attr, func.func_name)
        setattr(self, '__doc__', doc)
                                                                                                                               
    def __get__(self, obj=None, type=None):
        if not obj:
            return 'property'
        if self.fget:
            return getattr(obj, self.fget)()
                                                                                                                               
    def __set__(self, obj, arg):
        if self.fset:
            return getattr(obj, self.fset)(arg)
############ TEST ################
if __name__ == '__main__':
                                                                                                                               
    class A(object):
        def __init__(self):
            self._p = 1
        def _g(self):
            print 'inside A._g'
            return self._p
        def _s(self, p):
            print 'inside A._s'
            self._p = p
        p  = property (_g, _s, None, 'p doc')
        lp = lazyproperty (_g, _s, None, 'p doc')
                                                                                                                               
    class B(A):
        def _g(self):
            print '** inside B._g **'
            return self._p
                                                                                                                               
    b = B()
    print 'property in action'
    print ' ', b.p
    print 'lazyproperty in action'
    print ' ', b.lp
    b.p = 3

########## Solution II (Old one) #########
def rebind(cls):
                                                                                                                               
    props = [attr for attr in dir(cls) if type(getattr(cls, attr)) == property]
                                                                                                                               
    for prop_name in props:
        prop = getattr(cls, prop_name)
        getter_name = setter_name = destroyer_name = 'xxxxxxxx'
        if prop.fget:
            getter_name = prop.fget.__name__
        if prop.fset:
            setter_name = prop.fset.__name__
        if prop.fdel:
            destroyer_name = prop.fdel.__name__
        p_doc = prop.__doc__
        getter = getattr(cls, getter_name, None)
        setter = getattr(cls, setter_name, None)
        destroyer = getattr(cls, destroyer_name, None)
        setattr(cls, prop_name, property(getter, setter, destroyer, p_doc))

############ TEST ################
if __name__ == '__main__':
                                                                                                                                   class A(object):
        def __init__(self):
            self._p = 1
        def _g(self):
            print 'inside A._g'
            return self._p
        def _s(self, p):
            print 'inside A._s'
            self._p = p
        p = property(_g, _s, None, 'p doc')
                                                                                                                                   class B(A):
        def _g(self):
            print '** inside B._g **'
            return self._p
                                                                                                                               
    b = B()
    print b.p
    b.p = 3
                                                                                                                               
    rebind(B)
                                                                                                                               
    b = B()
    print b.p
    b.p = 3

History

  • revision 2 (18 years ago)
  • previous revisions are not available