Skip to main content
 首页 » 编程设计

python之如何理解Python的模块查找

2025年05月04日13lori

我在目录中创建了两个新文件,random.py 和 main.py。代码如下:

# random.py 
 
if __name__ == "__main__": 
    print("random") 
# main.py 
 
import random 
 
if __name__ == "__main__": 
    print(random.choice([1, 2, 3])) 

当我运行main.py文件时,程序报错。

Traceback (most recent call last): 
  File "main.py", line 8, in <module> 
    print(random.choice([1, 2, 3])) 
AttributeError: module 'random' has no attribute 'choice' 

Main.py 导入我自己定义的随机模块。

但是如果我在同一个目录下新建一个sys.py文件和一个main.py文件,代码如下:

# sys.py 
 
if __name__ == "__main__": 
    print("sys") 
# main.py 
 
import sys 
 
if __name__ == "__main__": 
    print(sys.path) 

当我运行 main.py 文件时,成功。

main.py 导入内置模块 sys。

为什么会有这么明显的区别?

脚本文件目录关系如下:

C:. 
    main.py 
    random.py 
    sys.py 

非常感谢您的回答。 请原谅我糟糕的英语。

请您参考如下方法:

sys 是一个内置 模块,这意味着它直接编译到 Python 可执行文件本身。当 Python 寻找模块时,内置模块优先于外部文件。标准的 random 模块不是内置的,所以它没有得到那种处理。

引用docs :

When the named module is not found in sys.modules, Python next searches sys.meta_path, which contains a list of meta path finder objects. These finders are queried in order to see if they know how to handle the named module...

Python’s default sys.meta_path has three meta path finders, one that knows how to import built-in modules, one that knows how to import frozen modules, and one that knows how to import modules from an import path (i.e. the path based finder).

由于内置模块的查找器出现在搜索导入路径的查找器之前,因此内置模块将在导入路径上的任何内容之前找到。

您可以在 sys.builtin_module_names 中看到您的 Python 内置的所有模块名称的元组。 .


也就是说,虽然任何内置模块都会优先于从文件加载的模块,但 sys 有其自己的特殊处理。 sys 是 Python 的基础构建 block 之一,sys 模块的大部分设置需要在导入系统功能足以正常导入过程运行之前进行。 sys 在解释器设置期间以绕过正常导入系统的方式明确创建,然后 sys 的 future 导入在 sys.modules 中找到它无需点击任何元路径查找器。

sys 的创建方式和位置是一个实现细节,因 Python 版本而异(并且在不同的 Python 实现中大不相同),但在 CPython 3.7.4 代码中,您可以查看它从 Python/pylifecycle.c 中的第 755 行开始.