Monkeypatching an object to become callable
gagsl-py2 at yahoo.com.ar
Thu Aug 13 09:19:05 CEST 2009
En Tue, 11 Aug 2009 20:21:16 -0300, Nikolaus Rath <Nikolaus at rath.org>
> Bruno Desthuilliers <bruno.42.desthuilliers at websiteburo.invalid> writes:
>> 7stud a écrit :
>>> class Wrapper(object):
>>> def __init__(self, obj, func):
>>> self.obj = obj
>>> self.func = func
>>> def __call__(self, *args):
>>> return self.func(*args)
>>> def __getattr__(self, name):
>>> return object.__getattribute__(self.obj, name)
>> This should be
>> return getattr(self.obj, name)
>> directly calling object.__getattribute__ might skip redefinition of
>> __getattribute__ in self.obj.__class__ or it's mro.
> Works nicely, thanks. I came up with the following shorter version which
> modifies the object in-place:
> class Modifier(obj.__class__):
> def __call__(self):
> return fn()
> obj.__class__ = Modifier
> To me this seems a bit more elegant (less code, less underscores). Or
> are there some cases where the above would fail?
I assume the above code is inside a function like make_callable(obj, fn)
Then, a new class is created for every instance you make callable; you may
want to cache all those classes (classes aren't cheap).
Might fail: when obj is not a new-style class, or its __class__ isn't
writable (e.g. builtin types).
More information about the Python-list