【发布时间】:2021-03-06 19:32:44
【问题描述】:
我想要一种方法来检测我的模块是否被直接执行,如import module 或from module import * 而不是import module.submodule(它也执行module),并在module 中访问此信息的__init__.py。
这是一个用例:
在 Python 中,一个常见的习惯用法是在模块的 __init__.py 文件中添加 import 语句,例如“扁平化”模块的命名空间并使其子模块可以直接访问。不幸的是,这样做会使加载特定子模块变得非常缓慢,因为在 __init__.py 中导入的所有其他同级模块也会执行。
例如:
module/
__init__.py
submodule/
__init__.py
...
sibling/
__init__.py
...
通过添加到module/__init__.py:
from .submodule import *
from .sibling import *
模块用户现在可以在不知道包结构细节的情况下访问子模块中的定义(即from module import SomeClass,其中 SomeClass 在submodule 的某处定义,并在其自己的__init__.py 文件中公开) .
但是,如果我现在直接运行submodule(如在import module.submodule 中,通过调用python3 -m module.submodule,甚至通过pytest 间接运行)我也会不可避免地执行sibling!如果兄弟姐妹很大,这可能会无缘无故减慢速度。
我想写 module/__init__.py 类似的东西:
if __???__ == 'module':
from .submodule import *
from .sibling import *
__???__ 为我提供了导入的完全限定名称。任何类似的机制也可以工作,尽管我最感兴趣的是一般情况(检测直接执行)而不是这个具体的例子。
【问题讨论】:
-
参考What does
if __name__ == "__main__":do? - 你可能正在寻找if __name__ != '__main__':,如果直接执行,则运行相反的效果,这可能是你正在寻找的。span> -
是的,这与我需要的非常相似,但它不太有效(据我了解)。使用
import module导入模块时,__name__设置为module,这与使用import module.submodule时无法区分,后者也将其设置为module。 -
这仅仅是因为执行
import module.submodule隐含地首先执行import module- 这就是为什么在执行import module.submodule之后,module被分配了对module.submodule父模块的适当引用(即module)。 -
这就是我的想法,但我不知道从这里去哪里。有什么方法可以在某处访问整个
module.submodule字符串吗?我查看了所有“dunder”变量,但似乎没有任何帮助。 -
基本上没有办法停止执行
module/__init__,py中的任何内容,也不会在从任何地方执行import module.submodule时向其显示任何特殊指示。
标签: python python-3.x module init