module with __call__ defined is not callable?

Steven D'Aprano steve at REMOVETHIScyber.com.au
Fri Feb 10 06:40:02 EST 2006


On Wed, 08 Feb 2006 07:14:04 -0500, Steve Holden wrote:

>>>Someone had to code Python so that it raised an error when you try to call
>>>a module object. Is there a reason why module() should not execute
>>>module.__call__()? I would have thought that by the duck typing principle,
>>>it shouldn't matter whether the object was a class, a module or an int, if
>>>it has a __call__ method it should be callable.
>>>
>> 
>> 
>> It would nice if you could make modules callable.
>> 
> Right. While we're at it, why don't we make strings callable. 

I don't believe strings have a __call__ method, nor do I see any
compelling case for giving one to them. But one could sub-class strings so
they had a __call__ method, in which case they should be callable. Just
like objects with a __len__ method work with len(), and objects with a
__getitem__ method are indexable.


> Calling a 
> string could call the function whose name (in some namespace or other) 
> was in the string. 

Or it could do whatever the __call__ method says it should do.


> And we can make integers callable too - that could 
> just assume that the integer was the address of a function to be called.

No, that wouldn't work, because Python doesn't have pointers. You can't
just jump to an address in memory and execute it. That would be Bad.


> In case you think I'm joking, I am.

I'm not.

> Why should a module be callable? What's the advantage? 

Modules could behave not only as collections of functions, methods,
classes etc., but as single entry-point functions themselves. Or, to put
it another way, modules are not just collections of code which gets called
by other code, but could also be tools in the Unix sense.

Here is a (trivial) hypothetical example:

py> import sillycase
py> sillycase("hello world")
hElLO wOrLd
py> sillycase.start_with_lowercase  # can still see the internals
True

A side-effect of this is you wouldn't need so many calls like glob.glob,
dis.dis or bisect.bisect.


If Python were smart enough to automatically execute the __call__ method
of a module (if it has one) when the module is given as a command line
argument, we could get rid of this boiler-plate code found in oh-so-many
scripts:

if __name__ == '__main__':
    main()  # __call__() would be better





> Should we be able 
> to add two modules together, yielding a module that contains all the 
> code of both modules? 

If modules had a __add__ method, then moduleA + moduleB should do whatever
the __add__ method says. Just as when you add a module to a class
instance, it will do whatever the class __add__ method says.

Frankly I can't think of anything useful adding two modules would do, but
maybe that's my failure of imagination.



-- 
Steven.




More information about the Python-list mailing list