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 :)