import ctypes
import itertools
# Make sure this matches the definition in the docs:
# https://docs.python.org/3/c-api/import.html#c._frozen
class _frozen(ctypes.Structure):
_fields_ = [('name', ctypes.c_char_p),
('code', ctypes.POINTER(ctypes.c_ubyte)),
('size', ctypes.c_int),
('is_package', ctypes.c_bool)]
PyImport_FrozenModules = ctypes.POINTER(_frozen).in_dll(ctypes.pythonapi, 'PyImport_FrozenModules')
if PyImport_FrozenModules:
for i in itertools.count():
record = PyImport_FrozenModules[i]
if record.name is None:
break
print(record.name)
# Extra for Python 3.11 and up
for name in ['_PyImport_FrozenBootstrap', '_PyImport_FrozenStdlib', '_PyImport_FrozenTest']:
records = PyImport_FrozenModules = ctypes.POINTER(_frozen).in_dll(ctypes.pythonapi, name)
for i in itertools.count():
record = records[i]
if record.name is None:
break
print(record.name)
如果您的目标是知道要避免使用哪些名称,那么您无需了解冻结模块。只要不选择内置函数、stdlib 模块或关键字的名称,您就没问题了。所以 matszwecja 链接的 3 个列表差不多。
但是了解冻结模块也很有趣,所以让我们来讨论一下这些。
冻结模块是未安装 Python 时无法执行的文件。“冻结”Python 程序会生成自定义可执行文件,其中包含 Python 解释器和程序所需的所有 Python 文件的嵌入式字节码。冻结模块是从嵌入式字节码加载的模块。
现在,该描述听起来好像冻结模块仅作为此类特殊可执行文件的一部分而存在,但标准 Python 解释器实际上确实带有一些冻结模块。其中一些被冻结是因为它们是导入系统本身的一部分,冻结它们使得在导入系统尚未准备好时更容易设置它们。其中一些被冻结是为了作为导入冻结模块的测试用例。在较新的 Python 版本中,一堆额外的 stdlib 模块也被冻结,因为它们是在 Python 启动时导入的,冻结它们可以加快启动速度。
我认为没有 Python 级别的接口可以查询冻结模块列表。最好的办法可能是阅读
Python/frozen.c
Python 版本的内容。如果需要,您可以访问C API,但他们在 Python 3.11 中添加了额外的冻结 stdlib 模块,从而改变了一些东西。在 3.10 及以下版本中,冻结的 stdlib 模块全部位于 documented
PyImport_FrozenModules
数组中,因此您可以读取以下内容:但从 3.11 开始,
PyImport_FrozenModules
默认为NULL
,并且冻结的 stdlib 模块已被移至 3 个未记录的数组中。如果您想访问未记录的 API,您可以这样做: