Python模块导入的层次结构是什么?

2024-06-16 08:29:04 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我在一个目录中有一个Python模块,在同一个目录中,我有一个以某种方式使用该模块的Python脚本

wdir
├── module
│   └── module_stuff
└── script.py

如果我在未安装模块的python环境中执行此文件,则在python从其源代码导入模块时,一切正常

问题是:如果我在这个Python环境中安装模块并继续以与以前相同的方式执行脚本,Python会从安装的模块还是从源代码导入模块?Python遵循什么样的hyerarchy来搜索每个导入?

为什么重要:如果我有一个脚本在执行过程中反复调用其他Python脚本并修改模块的源代码,那么会出现使用旧版本模块和新版本模块的结果,或者更糟糕的是,如果在模块代码中插入错误,可能会错过执行。但是,如果创建一个与测试环境分离的开发环境,这个问题就会得到解决


Tags: 模块文件py版本目录脚本环境源代码
2条回答

实际上,您可以自己尝试: 让我们构建并安装一个模块,然后对其进行修改,以查看谁更喜欢:

mymod | setup.py | mymod | myfun.py | __init__.py

setup.py包含:

from setuptools import setup, find_packages
setup(
    name='mymod',
    version='1.0',
    packages=find_packages(),
)

myfun.py包含:

def myfun():
    print('original Mod')

现在我们制作一个virtualenv并安装它:

virtualenv venv -p python3 
source venv/bin/activate
cd mymod
python setup.py install

现在我们转到python并导入

from mymod.mymod.myfun import myfun 

myfun()
# Returns original Mod

现在我们修改myfun.py而不安装它:

def myfun():
    print('Modified Mod')

我们回到python:

from mymod.mymod.myfun import myfun 

myfun()
# returns Modified Mod

所以看起来目录优先于模块,但是试试看

(注意,如果我们切换到一个目录,其中mymod.myfun不直接在我们的路径中,它将返回到打印原始mod)

这似乎取决于sys.path

引用https://docs.python.org/3/tutorial/modules.html#the-module-search-path

When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations: [edit: presumably in this order]

The directory containing the input script (or the current directory when no file is specified).

PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).

The installation-dependent default.

接着说

After initialization, Python programs can modify sys.path.

这对我来说意味着理论上任何事情都可能发生:-/

我猜module_stuff与内置名不相同,因此排除了第一个

您可能知道,Python不会在一次运行中两次导入同一个模块。也许您可以通过对module/module_stuff做一个小更改并再次运行来测试它

相关问题 更多 >