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