Object-based inheritance in Python

Tobias Windeln Tobias.Windeln at gmx.de
Fri Jan 9 08:37:54 EST 2004


Alexander Schmolck wrote:

> Tobias Windeln <Tobias.Windeln at gmx.de> writes:
> 
> 
>>Maybe there is a way to hand over self to the delegatee object.
> 
> [...]
> 
> 
>>class Child:
>>     def __init__(self, delegatee):
>>         self.__dict__['delegatee'] = delegatee
> 
> 
> Can't you just use this pattern:
> 
>            self.__dict__['delegatee'] = delegatee(self)

This results in:
AttributeError: Delegatee instance has no __call__ method


Here is the solution by Hans Nowaks 
(http://zephyrfalcon.org/download/selfish-0.4.2.zip):

##################################################################

import new
import types

__version__ = "0.4.2"
__author__ = "Hans Nowak"
__license__ = "python"
__cvsid__ = "$Id: selfish_v2.py,v 1.3 2003/09/22 04:30:50 hansn Exp $"

def rebind(method, obj):
     return new.instancemethod(method.im_func, obj, obj.__class__)

class SelfObject:

     def __init__(self):
         pass

     def __setattr__(self, name, value):
         if name.endswith("_p"):
             assert isinstance(value, SelfObject), \
                    "Only SelfObjects can be used for inheritance"
         if isinstance(value, types.FunctionType):
             m = new.instancemethod(value, self, self.__class__)
             self.__dict__[name] = m
         elif isinstance(value, types.UnboundMethodType):
             self.__dict__[name] = rebind(value, self)
         elif isinstance(value, types.MethodType):
             self.__dict__[name] = rebind(value, self)
         else:
             self.__dict__[name] = value

     def __getattr__(self, name):
         if name in self.__dict__.keys():
             # seems superfluous; if the attribute exists, __getattr__
             # isn't called
             return self.__dict__[name]
         else:
             # scan "ancestors" for this name...
             # left-right based on name, depth first
             items = self.__dict__.items()
             items.sort()
             for attrname, obj in items:
                 if attrname.endswith("_p"):
                     try:
                         z = obj.__getattr__(name)
                     except AttributeError:
                         pass
                     else:
                         if isinstance(z, types.MethodType):
                             z = rebind(z, self)
                         return z
             raise AttributeError, name

Object = SelfObject()




More information about the Python-list mailing list