Monkeypatching an object to become callable
7stud
bbxx789_05ss at yahoo.com
Sun Aug 9 20:55:26 EDT 2009
On Aug 9, 1:02 pm, Nikolaus Rath <Nikol... at rath.org> wrote:
> Hi,
>
> I want to monkeypatch an object so that it becomes callable, although
> originally it is not meant to be. (Yes, I think I do have a good reason
> to do so).
>
> But simply adding a __call__ attribute to the object apparently isn't
> enough, and I do not want to touch the class object (since it would
> modify all the instances):
>
> >>> class foo(object):
>
> ... pass
> ...>>> t = foo()
> >>> def test():
>
> ... print 'bar'
> ...>>> t()
>
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> TypeError: 'foo' object is not callable>>> t.__call__ = test
> >>> t()
>
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> TypeError: 'foo' object is not callable>>> t.__call__()
>
> bar
>
> Is there an additional trick to get it to work?
>
> Best,
>
> -Nikolaus
>
> --
> »Time flies like an arrow, fruit flies like a Banana.«
>
> PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6 02CF A9AD B7F8 AE4E 425C
With an old-style class your code will work:
class A:
pass
def test():
print "test"
a = A()
a.__call__ = test
a()
--output:--
test
a2 = A()
a2()
--output:--
a2()
AttributeError: A instance has no __call__ method
Another option is to use the *decorator pattern*. The decorator
pattern can be used when you want to add additional methods and
attributes to an object, and you don't want to disturb the original
class:
class A(object):
def __init__(self, x):
self.x = x
def sayhi(self):
print "hi"
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)
def test():
print "test"
a = A(10)
w = Wrapper(a, test)
w()
print w.x
w.sayhi()
--output:--
test
10
hi
More information about the Python-list
mailing list