object inheritance
Pradeep Jindal
praddyjindal at gmail.com
Fri Oct 26 08:31:50 EDT 2007
Can you tell any specific use case for doing this?
Regards,
Pradeep
On 10/26/07, Anand <anandology at gmail.com> wrote:
> I am trying to implement some kind of object inheritance. Just like
> one class can extend from another, I want to do the same on objects
> dynamically.
>
> I just thought that I can share my excitement here.
>
> Suppose there are classes A and B and their instances a and b.
>
> class A:
> def foo(self): self.say('foo')
> def say(self, msg):
> print 'a.say', msg
>
> class B:
> def say(self, msg):
> print 'b.say', msg
>
> a = A()
> b = B()
>
> I want b to inherit the behavior of a.
>
> >>> b.extend_from(a)
> >>> b.foo()
> b.say foo
>
> I looked around and found that some people talked about similar ideas,
> but didn't find any concrete implementation.
>
> I came up with the following implementation using meta-classes.
>
> class ExtendMetaClass(type):
> def __init__(cls, *a, **kw):
> # take all attributes except special ones
> keys = [k for k in cls.__dict__.keys() if not
> k.startswith('__')]
> d = [(k, getattr(cls, k)) for k in keys]
>
> # remove those attibutes from class
> for k in keys:
> delattr(cls, k)
>
> # remember then as dict _d
> cls._d = dict(d)
>
> def curry(f, arg1):
> def g(*a, **kw):
> return f(arg1, *a, **kw)
> g.__name__ = f.__name__
> return g
>
> def _getattr(self, name):
> """Get value of attribute from self or super."""
> if name in self.__dict__:
> return self.__dict__[name]
> elif name in self._d:
> value = self._d[name]
> if isinstance(value, types.MethodType):
> return curry(value, self)
> else:
> return value
> else:
> if self._super != None:
> return self._super._getattr(name)
> else:
> raise AttributeError, name
>
> def __getattr__(self, name):
> """Returns value of the attribute from the sub object.
> If there is no sub object, self._getattr is called.
> """
> if name.startswith('super_'):
> return self._super._getattr(name[len('super_'):])
>
> if self._sub is not None:
> return getattr(self._sub, name)
> else:
> return self._getattr(name)
>
> def extend_from(self, super):
> """Makes self extend from super.
> """
> self._super = super
> super._sub = self
>
> cls.__getattr__ = __getattr__
> cls._getattr = _getattr
> cls._super = None
> cls._sub = None
> cls.extend_from = extend_from
>
> class Extend:
> __metaclass__ = ExtendMetaClass
> def __init__(self, super=None):
> if super:
> self.extend_from(super)
>
> And the above example becomes:
>
> class A(Extend):
> def foo(self): self.say('foo')
> def say(self, msg):
> print 'a.say', msg
>
> class B(Extend):
> def say(self, msg):
> print 'b.say', msg
> # self.super_foo calls foo method on the super object
> self.super_say('super ' + msg)
>
> a = A()
> b = B()
>
> >>> b.extend_from(a)
> >>> b.foo()
> b.say foo
> a.say super foo
>
> There are one issue with this approach. Once b extends from a,
> behavior of a also changes, which probably should not. But that
> doesn't hurt me much.
>
> Any comments?
>
> --
> http://mail.python.org/mailman/listinfo/python-list
>
More information about the Python-list
mailing list