Christoph Böddeker's answer seems to be the best way to create a callable module, but as a comment says, it only works in Python 3.5 and up.
The benefit is that you can write your module like normal, and just add the class reassignment at the very end, i.e.
# coolmodule.py
import stuff
var = 33
class MyClass:
...
def function(x, y):
...
class CoolModule(types.ModuleType):
def __call__(self):
return 42
sys.modules[__name__].__class__ = CoolModule
and everything works, including all expected module attributes like __file__
being defined. (This is because you're actually not changing the module object resulting from the import at all, just "casting" it to a subclass with a __call__
method, which is exactly what we want.)
To get this to work similarly in Python versions below 3.5, you can adapt Alex Martelli's answer to make your new class a subclass of ModuleType, and copy all the module's attributes into your new module instance:
#(all your module stuff here)
class CoolModule(types.ModuleType):
def __init__(self):
types.ModuleType.__init__(self, __name__)
# or super().__init__(__name__) for Python 3
self.__dict__.update(sys.modules[__name__].__dict__)
def __call__(self):
return 42
sys.modules[__name__] = CoolModule()
Now __file__
, __name__
and other module attributes are defined (which aren't present if just following Alex's answer), and your imported module object still "is a" module.
from mymodule import __call__
? – Teratismfrom tqdm import tqdm
but they didn't apply this trick. – Stipulate