Monkeypatching an object to become callable
Gabriel Genellina
gagsl-py2 at yahoo.com.ar
Thu Aug 13 03:19:05 EDT 2009
En Tue, 11 Aug 2009 20:21:16 -0300, Nikolaus Rath <Nikolaus at rath.org>
escribió:
> Bruno Desthuilliers <bruno.42.desthuilliers at websiteburo.invalid> writes:
>> 7stud a écrit :
>> (snip)
>>> 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).
--
Gabriel Genellina
More information about the Python-list
mailing list