changing __call__ on demand
Steven Bethard
steven.bethard at gmail.com
Mon Feb 14 15:37:54 EST 2005
F. Petitjean wrote:
> Le Sun, 13 Feb 2005 13:19:03 -0500, Hans Nowak a écrit :
>>Note that it works just fine if you don't use a new-style class:
>>
>>>>>class Test:
>>
>>... def __init__(self):
>>... self.__call__ = self.foobar
>>... def foobar(self, *args, **kwargs):
>>... print "Called with:", args, kwargs
>>...
>>
>>>>>t = Test()
>>>>>t()
>>
>>Called with: () {}
>>
>>>>>t(3, 4)
>>
>>Called with: (3, 4) {}
>>
>>>>>t(42, x=0)
>>
>>Called with: (42,) {'x': 0}
>
> Are you sure that if you add a __call__() method, it will still work
> fine ?
Simple enough to check, isn't it?
py> class C:
... def __init__(self):
... self.__call__ = lambda: "__init__"
... def __call__(self):
... return "__call__"
...
py> C()()
'__init__'
Old-style classes lookup methods like __call__ on the instance[1].
New-style classes look them up on the type:
py> class C:
... def __init__(self):
... self.__iter__ = lambda: iter(["__init__"])
... def __iter__(self):
... return iter(["__call__"])
...
py> list(C())
['__init__']
py> class C(object):
... def __init__(self):
... self.__iter__ = lambda: iter(["__init__"])
... def __iter__(self):
... return iter(["__call__"])
...
py> list(C())
['__call__']
AFAICT, non-magic methods are looked up on instance first:
py> class C:
... def __init__(self):
... self.f = lambda: "__init__"
... def f(self):
... return "__call__"
...
py> C().f()
'__init__'
py> class C(object):
... def __init__(self):
... self.f = lambda: "__init__"
... def f(self):
... return "__call__"
...
py> C().f()
'__init__'
STeVe
[1] Well, they look there first.
More information about the Python-list
mailing list