Neal Becker wrote: > Simon Brunning wrote: > >> On 10 March 2010 13:12, Neal Becker <ndbeck...@gmail.com> wrote: >>> Want to switch __call__ behavior. Why doesn't this work? What is the >>> correct way to write this? >>> >>> class X (object): >>> def __init__(self, i): >>> if i == 0: >>> def __call__ (self): >>> return 0 >>> else: >>> def __call_ (self): >>> return 1 >>> >>> >>> x = X(0) >>> >>> x() >>> TypeError: 'X' object is not callable >> __call__ is in the __init__ method's local namespace - you need to >> bind it to the class's namespace instead: >> >> X.__call__ = __call__ >> >> But this probably isn't what you want either, since all instances of X >> will share the same method. >> >> What are you trying to do? In your simple example, you'd be much >> better off with a single __call__ method. But you knew that. >> > > Sorry, a bit early in the morning. This works: > class X (object): > def __init__(self, i): > if i == 0: > def F (self): > return 0 > else: > def F (self): > return 1 > self.F = F > > def __call__ (self): > return self.F (self) > > > Not sure if there is a more elegant (or compact) way to write this. > Could __call__ be defined directly within __init__? > > What I'm trying to do is make a callable whose behavior is switched based on > some criteria that will be fixed for all calls. In my example, this will > ultimately be determined by the setting of a command line switch.
ISTM it would be prettiest to do: class X(object): def __init__(self, i): self.flag = i == 0 def __call__(self): if self.flag: return 0 else: return 1 Or, if the comparison isn't particularly expensive, it would look nicer to just use self.i and do "self.i == 0" in __call__. Not that it matters, but this is probably faster than your version, too, since it saves a method call. By the way, IIRC Python only looks up double-underscore methods on the class, not the instance. That's why you had to indirect through self.F. -- Matt Nordhoff -- http://mail.python.org/mailman/listinfo/python-list