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