[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

Re: Can't define __call__ within __init__?

Matt Nordhoff

3/10/2010 1:58:00 PM

Neal Becker wrote:
> Simon Brunning wrote:
>
>> On 10 March 2010 13:12, Neal Becker <ndbecker2@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