在Python 3.8中,建议为虚拟环境添加替代方案-带有PEP 582软件包的本地目录Python本地软件包目录 。
该PEP建议添加一种机制,以自动检测Python中的__pypackages__
目录,并在将其导入为已安装软件包的源时使用它。 __pypackages__
目录在导入时的优先级高于全局或自定义软件包目录。 这将防止创建,激活或停用虚拟环境。
这是使用__pypackages__
的包结构在Python 3.8中的样子:
foo __pypackages__ 3.8 lib bottle myscript.py
在本文中,我将向您展示如何在不等待Python 3.8退出的情况下将本地目录与软件包一起使用。
本文介绍了在Linux Python 3.5中测试过的基本示例。 对于其他平台,您可能需要进行更改。
在本地目录中安装软件包
除了--target
选项外,安装几乎与使用pip安装软件包相同。 在其中,我们使用本地软件包指示目录的完整或相对路径。
pip3 install --target="$PWD/__pypackages__/3.5/lib/" bar
$ PWD是当前工作目录中的变量。
将创建以下目录树:
foo __pypackages__ 3.5 lib bar myscript.py
必须手动指定Python版本和子目录。
如果您需要使用二进制代码针对不同的体系结构安装软件包,则可能还会出现问题。 我没有此类软件包,但作为解决方案,您可以在目录结构中添加更多架构。
另一个安装选项还有另一种在特定目录中安装软件包的方法:
pip3 install --ignore-installed --install-option="--prefix=$PWD/__pypackages__" --install-option="--no-compile" bar
但是您必须指定安装位置的完整路径,并且目录树将与PEP 582中建议的目录树不同:
foo __pypackages__ lib python3.5 site-packages bar myscript.py
将本地目录与软件包一起使用
安装软件包之后,仍然要告诉解释器在哪里寻找依赖项。
为此,将路径添加到本地目录,并将包添加到sys.path
列表中。 将路径添加到主模块(第一个加载的模块)就足够了,而不必添加到其余模块。 之后,您可以导入本地安装的软件包。
import os import sys _PATH = '/__pypackages__/3.5/lib/' sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)) + _PATH) import bar
唯一的条件是主模块必须与__pypackages__
目录处于同一嵌套级别。
告诉Python在哪里寻找软件包的另一种方法是在运行脚本之前设置环境变量。
PYTHONPATH="$PWD/__pypackages__/3.5/lib/:$PYTHONPATH" python3 ./myscript.py
用这种简单的方法,您现在可以实现类似于PEP 582的功能。