Callable assertion?

Gonçalo Rodrigues op73418 at mail.telepac.pt
Mon Oct 6 09:08:49 EDT 2003


On Mon, 6 Oct 2003 11:52:12 +0200, Gerrit Holl <gerrit at nl.linux.org>
wrote:

>Gonçalo Rodrigues wrote:
>> On Sun, 05 Oct 2003 10:20:11 -0400, Roy Smith <roy at panix.com> wrote:
>> > "A.M. Kuchling" <amk at amk.ca> wrote:
>> >> There's a callable(param) built-in function, dating back to Python 1.2.
>
>> >What does "appears callable" mean?  Under what circumstances would 
>> >callable(foo) return True, yet foo() would fail?
>> 
>> An extreme and artificial example:
>> 
>> >>> class FakeCallable(object):
>> ... 	def __call__(self, *args, **kwargs):
>> ... 		raise TypeError("My only purpose in life is to trick
>> the Python interpreter.")
>> ... 
>> >>> a = FakeCallable()
>> >>> callable(a)
>> True
>> >>> a()
>> Traceback (most recent call last):
>>   File "<interactive input>", line 1, in ?
>>   File "<interactive input>", line 3, in __call__
>> TypeError: My only purpose in life is to trick the Python interpreter.
>
>Is there a difference between callable(a) and hasattr(a, '__call__')?
>

Definitely yes. There are a few strange objects that are callable and
do not have a __call__. And you can make up your own:

>>> class Wrapper(object):
... 	def __init__(self, obj):
... 		super(Wrapper, self).__init__(obj)
... 		self.__obj = obj
... 	def __getattr__(self, attrib):
... 		return getattr(self.__obj, attrib)
... 	
>>> a = Wrapper(lambda *args, **kwargs: None)
>>> a
<__main__.Wrapper object at 0x010D4D50>
>>> hasattr(a, "__call__")
True
>>> a()
Traceback (most recent call last):
  File "<interactive input>", line 1, in ?
TypeError: 'Wrapper' object is not callable
>>> 

The gist is that the lookup for special methods does not use the usual
getattr machinery but just crawls the class's mro in search of it.

With my best regards,
G. Rodrigues




More information about the Python-list mailing list