Christoph Böddeker 的回答似乎是创建可调用模块的最佳方式,但正如评论所说,它仅适用于 Python 3.5 及更高版本。
好处是您可以像平常一样编写模块,只需在最后添加类重新分配,即
# 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
一切正常,包括所有预期的模块属性,如__file__
被定义。(这是因为您实际上根本没有更改导入产生的模块对象,只是使用__call__
方法将其“强制转换”为子类,这正是我们想要的。)
为了让它在低于 3.5 的 Python 版本中同样工作,您可以调整Alex Martelli 的答案,使您的新类成为 ModuleType 的子类,并将所有模块的属性复制到您的新模块实例中:
#(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()
现在__file__
,__name__
定义了其他模块属性(如果只是按照亚历克斯的回答则不存在),并且您导入的模块对象仍然是“是”模块。