我正在阅读Python 文档以了解如何解析导入,然后发现了这一点
... 解释器首先搜索具有该名称的内置模块。这些模块名称列在 sys.builtin_module_names 中。如果未找到,它会在变量 sys.path 给出的目录列表中搜索名为 spam.py 的文件。sys.path 从以下位置初始化:
包含输入脚本的目录(未指定文件时为当前目录)。
PYTHONPATH(目录名称列表,语法与 shell 变量 PATH 相同)。...
因此 python 首先查看sys.builtin_module_names
然后查看sys.path
。因此我在我的操作系统 (Mac) 上检查了 sys.builtin_module_names。
>>> sys.builtin_module_names
('_abc', '_ast', '_codecs', '_collections', '_functools', '_imp', '_io', '_locale', '_operator', '_signal', '_sre', '_stat', '_string', '_suggestions', '_symtable', '_sysconfig', '_thread', '_tokenize', '_tracemalloc', '_typing', '_warnings', '_weakref', 'atexit', 'builtins', 'errno', 'faulthandler', 'gc', 'itertools', 'marshal', 'posix', 'pwd', 'sys', 'time')
>>> 'os' in sys.builtin_module_names
False
由于os
不在中sys.builtin_module_names
,因此与我的 python 文件位于同一目录中的文件os.py
应该优先于os
python 模块。
我使用以下简单代码os.py
在目录中创建了一个名为的文件:test
#os.py
def fun():
print("Custom os called!")
并创建另一个名为test.py
imports 的文件os
#test.py
import sys
print("os in sys.builtin_module_names -", 'os' in sys.builtin_module_names)
print("First directory on sys -", sys.path[0])
import os
print("source file of the imported os -", os.__file__)
print(os.fun())
这是输出test.py
> python3 test.py
os in sys.builtin_module_names - False
First directory on sys - /Users/dhruv/Documents/test
source file of the imported os - /opt/homebrew/Cellar/[email protected]/3.13.1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/os.py
Traceback (most recent call last):
File "/Users/dhruv/Documents/test/test.py", line 9, in <module>
print(os.fun())
^^^^^^
AttributeError: module 'os' has no attribute 'fun'
为什么调用python os模块?
sys.path
按照教程中所说的方式进行初始化,但是 Python 需要os
模块才能完全完成初始化。os
在 Python 设置期间是必需的。它由模块导入,除非您手动表示不要这样做(使用标志),否则模块会在 Python 设置期间导入。site
-S
这些导入发生得太早了,Python 解释器实际上还没有决定要运行哪个 Python 程序。它会在稍后弄清楚。而且
sys.path
在决定脚本是什么之前,它无法将脚本目录添加到其中。因此,在设置的早期阶段,脚本目录尚未打开
sys.path
,并且导入不会搜索脚本目录。Python 无法os.py
在早期阶段找到您。现在,在较新的 Python 版本中,还有另一件事需要考虑。在 Python 3.11 及更高版本中,开发人员决定冻结一堆用 Python 编写的模块,这些模块在 Python 启动时是必需的。这会将它们的字节码直接嵌入到 Python 可执行文件中,这有助于加快启动速度。
本教程未提及冻结模块 - 教程通常会掩盖此类模糊细节。在内置模块之后和搜索之前搜索冻结模块
sys.path
。os
是冻结的模块之一,因此在 Python 3.11 及更高版本中,的 stdlib 版本os
将优先于脚本目录中的 ,即使完全初始化os.py
后也是如此。sys.path