CPython 3与PyPy3内置模块路径解析及特殊模块导入规则咨询
Python模块导入优先级:CPython vs PyPy 的差异解析
先来看你做的测试命令,我把它整理成代码块方便查看:
touch sys.py touch parser.py python3 -c 'import sys; print(sys)' pypy3 -c 'import sys; print(sys)' python3 -c 'import parser; print(parser)' pypy3 -c 'import parser; print(parser)'
你观察到的现象拆解
sys模块的一致行为:不管是CPython还是PyPy,都会直接忽略当前目录下的sys.py,优先加载内置的sys模块——这是因为sys属于Python实现的核心内置模块,优先级最高,不受sys.path影响。parser模块的差异行为:- CPython侧:
parser并不是严格意义上的“内置模块”,它属于标准库中的C扩展模块,以文件形式存在于系统路径中。所以导入时会遵循sys.path的查找顺序:- 如果当前目录在
sys.path里(默认是首位),且存在parser.py,就会优先导入这个本地文件; - 切换到其他目录执行时,
sys.path里没有本地的parser.py,就会加载标准库中的parser模块,所以会显示具体路径而非(built-in);
- 如果当前目录在
- PyPy侧:PyPy为了优化性能和兼容性,把
parser这类常用标准库模块直接整合进了虚拟机,当作内置模块处理,优先级和sys一致,所以不管sys.path里有没有同名文件,都会优先加载内置版本。
- CPython侧:
相关文档参考
其实核心的导入规则在Python官方的模块导入系统章节有说明,但不同实现的细节差异需要看各自的文档:
- CPython:你可以在CPython的文档中找到关于
sys.path查找顺序的详细说明——导入时会按sys.path的顺序依次查找同名的.py/.pyc/扩展模块文件,只有当完全找不到匹配项时,才会尝试加载内置模块(注意:sys这类核心内置模块是跳过sys.path直接加载的)。另外,parser属于标准库的扩展模块,而非核心内置,所以会遵循sys.path的规则。 - PyPy:PyPy的官方文档在“标准库兼容性”部分提到,为了提升执行效率,他们会将部分常用标准库模块预加载为内置模块,这些模块的导入优先级等同于
sys,不会被sys.path中的同名文件覆盖。
虽然你知道这是不良实践,但这种实现细节确实比较分散,需要结合主Python文档和具体实现的文档来梳理。
内容的提问来源于stack exchange,提问作者Labo
相关产品推荐
相关产品推荐

