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