Overriding member methods in __init__

Hrvoje Niksic hniksic at xemacs.org
Mon Dec 3 10:36:18 EST 2007


c james <cjames at callone.net> writes:

>> class YesNo(object):
>>    def __init__(self, which):
>>      self.which = which
>> 
>>    def __call__(self, val):
>>      return (self.no, self.yes)[self.which](val)
>> 
>>    def yes(self, val):
>>      print 'Yes', val
>> 
>>    def no(self, val):
>>      print 'No', val
>
> Thanks, I was trying to eliminate another level of indirection with a
> test at each invocation of __call__

Allowing instance lookup of __call__ would slow down normal uses of
the internal __call__ mechanism.  Since it used for all function and
method calls, it needs to remain extremely fast.  If you're really
worried about performance, you can define YesNo.__new__ to return
either a Yes instance or a No instance, depending on the value:

class YesNo(object):
    def __new__(cls, which):
        if which:
            return object.__new__(Yes)
        else:
            return object.__new__(No)

    def yes(self, val):
        print 'Yes', val

    def no(self, val):
        print 'No', val

class Yes(YesNo):
    def __call__(self, val):
        self.yes(val)          # no check at every call

class No(YesNo):
    def __call__(self, val):
        self.no(val)           # likewise

>>> x = YesNo(True)
>>> x
<__main__.Yes object at 0xb7d0ee8c>
>>> x('foo')
Yes foo
>>> y = YesNo(False)
>>> y
<__main__.No object at 0xb7d0eeec>
>>> y('foo')
No foo
>>> isinstance(x, YesNo)
True
>>> isinstance(y, YesNo)
True



More information about the Python-list mailing list