module not callable - why not?

Hans Nowak hans at zephyrfalcon.org
Fri Apr 9 15:54:48 EDT 2004


Diez B. Roggisch wrote:

> Now I thought about defining a __call__ operator at module level to allow
> this:
> 
> import quaternion
> 
> q = quaternion()
> 
> 
> where the call looks like this:
> 
> def __call__(*a, *kw):
>     return quaternion()
> 
> But that doesn't work. 
> 
> Now my question is: Is there a way to make a module callable that way? And
> wouldn't it make sense to allow the implementation of a call operator on
> module level?

Is is possible, if you use packages, and are willing to use some evil hackery. 
:-)  Here's what to do:

1. Create a package 'quaternion'.

2. Create quaternion/__init__.py:

# quaternion/__init__.py

from types import ModuleType
import os, sys

class QuaternionModule(ModuleType):
     def __init__(self):
         import _quaternion
         self.__name__ = "_quaternion proxy"
         self.__file__ = __file__
         self.__base = os.path.dirname(__file__)
         self.__module = sys.modules['quaternion']

     def __call__(self):
         return _quaternion.quaternion()

sys.modules['quaternion'] = QuaternionModule()
del sys, os, ModuleType, QuaternionModule

3. Create quaternion/_quaternion.py:

# _quaternion.py

class quaternion:
     def foo(self, x):
         return x*2

(obviously a dummy implementation, but you get the idea)

4. Test it:

Python 2.3.3 (#51, Dec 18 2003, 20:22:39) [MSC v.1200 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
 >>> import quaternion
 >>> q = quaternion()
 >>> q.foo(42)
84
 >>>

To be fair, this is an adaptation of some code sent to me by Olivier Poyen.  It 
was originally a construct to add dynamic import to my Wax library (which 
currently imports a bunch of modules in its __init__.py, taking up time and 
space, whether you use them or not).

Now, whether this good coding practice is something else entirely... :-)

Cheers,

-- 
Hans (hans at zephyrfalcon.org)
http://zephyrfalcon.org/






More information about the Python-list mailing list