What I want to do is something like:
class Foo(object):
def __init__(self):
pass
def f(self):
print "f"
def g(self):
print "g"
# programatically set the "default" operation
fer=Foo()
fer.__call__=fer.f
# a different instance does something else as its
# default operation
ger=Foo()
ger.__call__=ger.g
fer() # invoke different functions on different
ger() # objects depending on how they were set up.
But as of 2.7 (which I’m currently using) I can’t do this, the attempts at fer()
raise an exception.
Is there a way to, in effect, set a per instance __call__ method?
The normal stuff with
types.MethodTypeunfortunately doesn’t work here since__call__is a special method.From the data model:
This is slightly ambiguous as to what is actually called, but it’s clear that your class needs to have a
__call__method.You’ll need to create some sort of hack:
Careful with this though, it’ll result in an infinite recursion if you don’t set a
__call__on an instance before you try to call it.Note that I don’t actually recommend calling the magic attribute that you rebind
__call__. The point here is to demonstrate that python translates:f()intof.__class__.__call__(f)and so there’s nothing you can do to change it on a per-instance basis. the class’s__call__will be called no matter what you do — You just need to do something to change the behavior of the class’s__call__per-instance which is easily achieved.You could use a setter type thing to actually create methods on your class (rather than simple functions) — and of course that could be turned into a property: