In python, a "function object", that is to say an object which can be called as a function, is simply an instance of a class which has a __call__
method. An example is
class FuncObj(object):
def __call__(self, *args):
print("args were %s." % str(args))
func = FuncObj()
func(1,2,3) # output -> args were (1, 2, 3)
Since this object is callable, we may want to install it as a method in another class. Suppose I create a class and and instance like this
class Thing(object):
pass
thing = Thing()
how can I add a method foo
in the class Thing
so that the call thing.foo(3)
is equivalent to func(thing, 3)
?
The naive way to do this doesn't work:
Thing.foo = func
thing.foo(3) # -> output: args were (3,)
the instance 'thing' is not passed to func.__call__
, as one would expect from an instance method. Second try
Thing.foo = func.__call__
thing.foo(3) # same failure: args were (3,)
I ended up wrapping func
into a true function like this
def asFunction(obj, name=""):
def wrapper(*args, **kwd):
return obj(*args, **kwd)
if name:
wrapper.__name__ = name
wrapper.wrapped = obj
return wrapper
# third try
Thing.foo = asFunction(func, "foo")
thing.foo(3) # output: args were (<main.Thing object...>, 3) Success !
thing.foo.wrapped # <- access to the wrapped object func through Thing.foo.
Any comments ?
If someone knows a better way to do this, please add to this thread :)