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