Neal Becker wrote: > Steven D'Aprano wrote: > >> On Wed, 10 Mar 2010 08:12:14 -0500, Neal Becker 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 >> >> Others have already pointed out that there are two reasons that won't >> work: >> >> (1) you define __call__ as a local variable of the __init__ method which >> then disappears as soon as the __init__ method completes; and >> >> (2) special methods like __call__ are only called on the class, not the >> instance, so you can't give each instance its own method. >> >> >> Perhaps the best way to solve this is to use delegation: >> >> >> def zero_returner(): >> return 0 >> >> def one_returner(): >> return 1 >> >> >> class X (object): >> def __init__(self, i): >> if i == 0: >> self.func = zero_returner >> else: >> self.func = one_returner >> def __call__(self, *args, **kwargs): >> return self.func(*args, **kwargs) >> >> >> zero_returner and one_returner can be any callable object, not >> necessarily a function. >> >> Of course, all this assumes that your solution isn't even simpler: >> >> class X (object): >> def __init__(self, i): >> self.i = i >> def __call__(self): >> return self.i >> >> but I assume if it was that simple, you would have done that already. >> >> >> > The example I showed was just a toy problem. The real problem is > I expect to call a function many times, and I want to avoid the overhead of > the 'if blah' everytime. > This is a premature optimization. First, make it work. Then (if it doesn't work fast enough) make it work faster.
regards Steve -- Steve Holden +1 571 484 6266 +1 800 494 3119 See PyCon Talks from Atlanta 2010 http://pycon.blip.tv/ Holden Web LLC http://www.holdenweb.com/ UPCOMING EVENTS: http://holdenweb.eventbrite.com/ -- http://mail.python.org/mailman/listinfo/python-list