Callable modules?
Pekka Pessi
Pekka.Pessi at nokia.com
Tue Jul 30 19:02:10 EDT 2002
Paul Rubin <phr-n2002b at NOSPAMnightsong.com> writes:
>Is there a way to do that? I tried putting
> def __call__(x): ...
>into foo.py but that didn't work.
There is no magic in a __call__ attribute. Python language
reference does not promise you anything about it. For example,
>>> class O(object):
... pass
...
>>> o = O()
>>> o.__call__ = lambda x: x * x
>>> o(1)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: 'O' object is not callable
However, the __call__ method is special:
>>> class O2(object):
... def __call__(self, x):
... return x * x
...
>>> o2 = O2()
>>> o2(2)
4
The function __call__ you added to the module is an attribute,
not a method, so it does not have any magic.
(The __call__ attribute does work on instances, but I think it
is considered as a bug.)
>>> class I:
... pass
...
>>> i = I()
>>> i.__call__ = lambda x: x * x
>>> i(2)
1
Now, back to your question. You can have a callable module, no
problem:
>>> import types
>>> class module(types.ModuleType):
... def __call__(self, x): return x * x
...
>>> module()(2)
4
If you want to call the __call__ attribute, that is a
no-brainer, too:
>>> class module(types.ModuleType):
... def __call__(self, *x, **kw):
... try:
... func = getattr(self, "__call__")
... return apply(func, x, kw)
... except AttributeError:
... raise TypeError("'%s' module is not callable." % (self.__name__,))
...
>>> m = module()
>>> m.__call__ = lambda x: x * x
>>> m(2)
4
You can propably find out rest of the gory details by looking
around in imp and knee modules.
>If there's not a way to do this already, maybe it's a reasonable
>addition.
Guido disagrees, I'm afraid. I have asked twice, and got nixed
twice.
Pekka
More information about the Python-list
mailing list