Python 的 module(模块)
**【官方文档】**位置:https://docs.python.org/zh-cn/3/library/stdtypes.html#modules
模块唯一的特殊操作是属性访问:
m.name
,这里 m 为一个模块而 name 访问定义在 m 的符号表中的一个名称。 模块属性可以被赋值。 (请注意import
语句严格来说也是对模块对象的一种操作;import foo
不要求存在一个名为 foo 的模块对象,而是要求存在一个对于名为 foo 的模块的 (永久性) 定义。)每个模块都有一个特殊属性
__dict__
。 这是包含模块的符号表的字典。 修改此字典将实际改变模块的符号表,但是无法直接对__dict__
赋值 (你可以写m.__dict__['a'] = 1
,这会将m.a
定义为1
,但是你不能写m.__dict__ = {}
)。 不建议直接修改__dict__
。内置于解释器中的模块会写成这样:
<module 'sys' (built-in)>
。 如果是从一个文件加载,则会写成<module 'os' from '/usr/local/lib/pythonX.Y/os.pyc'>
。
其中,<module 'os' from '/usr/local/lib/pythonX.Y/os.pyc'>
中的 os
为模块名,/usr/local/lib/pythonX.Y/os.pyc
为模块对应 py 或 pyc 文件路径。
module 的使用场景
for module_name, module_obj in sys.modules.copy().items():
pass
在使用以上逻辑遍历 sys.modules
时(根据 Python 文档,为避免并发问题,在遍历 sys.modules
时建议使用 .copy()
),键 module_name
为模块名,值 module_obj
为 module。
但是,module_obj
也会存在部分非 moidule
的 class
,例如:<class 'typing.io'>
。要区分 module 和 class,可以通过查看 module 对象和 class 对象的类名称,即 module_obj.__class__.__name__
;此时 module 的类名称为 module
,class 的类名称为 type
。
module 模块信息获取方法
要获取 module
类中的信息,可以通过 module.__spec__
获取,module.__spec__
的类型为 Optional[ModuleSpec]
,即为 ModuleSpec
或 None
。
**【
module.__spec__
的官方文档】**位置:https://docs.python.org/zh-cn/3/reference/import.html#spec__
根据当前了解,仅有以下 2 种情况下,module.__spec__
为 None
:
- 启动主模块(
__main__
) cython
相关的模块(例如cython_runtime
、_cython_0_29_35
)
对于非空的 ModuleSpec
,执行打印(即执行 ModuleSpec.__repr__
)的结果样例如下。通常来说,name
、loader
和 origin
这 3 个属性一定存在,其中 name
为模块名,loader
为模块加载器,origin
为对应的 py 脚本路径。部分模块还包含 submodule_search_locations
属性,为搜索子模块的路径。例如:
ModuleSpec(name='numpy', loader=<_frozen_importlib_external.SourceFileLoader object at 0x00000213EF0A8C70>, origin='D:\\py\\Python310\\lib\\site-packages\\numpy\\__init__.py', submodule_search_locations=['D:\\py\\Python310\\lib\\site-packages\\numpy'])
origin
不为 py 脚本路径的情况:
- 内置模块,
loader
为<class '_frozen_importlib.BuiltinImporter'>
,origin
为built-in
。 _frozen_importlib
、_frozen_importlib_external
、zipimport
、importlib._bootstrap
和importlib._bootstrap_external
这 5 个特殊的内置模块,loader
为<class '_frozen_importlib.FrozenImporter'>
,origin
为frozen