[Python-Dev] Missing operator.call

Jean-Paul Calderone exarkun at divmod.com
Wed Feb 4 20:49:27 CET 2009


On Wed, 4 Feb 2009 10:50:47 -0800, Brett Cannon <brett at python.org> wrote:
>On Wed, Feb 4, 2009 at 10:43, Steven Bethard <steven.bethard at gmail.com> wrote:
>> [snip]
>>
>> Not sure I follow you here. It's not the __init__ that allows you to
>> do ``x()``, it's the fact that the class declares a __call__, right?
>>
>>>>> class C(object):
>> ...     pass
>> ...
>>>>> C.__call__()
>> <__main__.C object at 0x01A3C370>
>>>>> C()
>> <__main__.C object at 0x02622EB0>
>>>>> str.__call__()
>> ''
>>>>> str()
>> ''
>>
>
>I don't think so::
>
>>>> Foo.__call__
><method-wrapper '__call__' of type object at 0x81cee0c>
>>>> Foo.__call__ = lambda: None
>>>> Foo.__call__
><unbound method Foo.<lambda>>
>>>> Foo()
><__main__.Foo object at 0xf7f90e8c>

That's because the __call__ special on an instance is ignored, as many
specials on new-style instances are ignored.  If you change the method
where it counts - on type(Foo) in this case - then you see something
different.

    >>> class X(type):
    ...     def __call__(self, *a, **kw):
    ...             print 'X.__call__', a, kw
    ...             return super(X, self).__call__(*a, **kw)
    ...
    >>> class Y(object):
    ...     __metaclass__ = X
    ... 
    >>> Y.__call__
    <bound method X.__call__ of <class '__main__.Y'>>
    >>> Y()
    X.__call__ () {}
    <__main__.Y object at 0xb7d0706c>
    >>> Y.__call__ = lambda: None
    >>> Y.__call__
    <unbound method Y.<lambda>>
    >>> Y()
    X.__call__ () {}
    <__main__.Y object at 0xb7d0706c>
    >>> X.__call__ = lambda: None
    >>> Y()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: <lambda>() takes no arguments (1 given)
    >>>

As far as I know, Steven Bethard's point is correct.

Jean-Paul


More information about the Python-Dev mailing list