PYTHONPATH 与符号链接

6 投票
3 回答
3095 浏览
提问于 2025-04-17 14:26

昨天,我修改了我的虚拟环境中的 bin/activate 脚本,让它设置了 PYTHONPATH 环境变量,以便包含某个外部包的开发版本。我之所以这么做,是因为这个包的 setup.py 使用了 distutils,而不支持像 setuptools 那样的 develop 命令。设置 PYTHONPATH 在终端使用 Python 解释器时效果很好。

不过,我刚刚打开了 PyCharm 的项目设置,发现 PyCharm 并不知道这个外部包的存在——它既没有列出这个包,也没有显示它的路径。自然,这是因为 PyCharm 无法(也不可能可靠地)解析或加载 bin/activate 脚本。我可以手动在 PyCharm 的项目设置中添加路径,但这就意味着我得重复操作(一次在 bin/activate,再一次在 PyCharm 的项目设置中)。这样做不符合 DRY 原则,挺麻烦的。

site-packages 中创建一个指向外部包的符号链接几乎是完美的。这样,至少 PyCharm 的源代码编辑器能找到这个包,终端中的 Python 解释器也能找到。不过,不知怎么的,PyCharm 仍然没有在项目设置中列出这个包,我也不确定这样放着是否合适。

那么,我该如何将外部包添加到我的虚拟环境/项目中,以便……

  1. 我不需要重复操作;并且……
  2. Python 解释器和 PyCharm 都能识别它?

3 个回答

-1

这是对ndpu回答的一个改进,适用于无论真实文件在哪里的情况。

你可以先解除符号链接的引用,然后在导入本地模块之前设置sys.path

import os.path
import sys

# Ensure this file is dereferenced if it is a symlink
if __name__ == '__main__' and os.path.islink(__file__):
    try:
        sys.path.remove(os.path.dirname(__file__))
    except ValueError:
        pass
    sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))

# local imports go here
-1

一种方法是动态添加路径:

try:
    import foo
except ImportError:
    sys.path.insert(0. "/path/to/your/package/directory")
    import foo

不过这并不是最好的解决方案,因为这段代码很可能不会被包含在应用的最终版本中。还有一种选择(我觉得更合适)是创建一个简单的setup.py文件,用于打包,然后在虚拟环境中使用开发参数进行部署,或者通过pip使用-e参数:

python setup.py develop 

或者:

pip install -e /path/to/your/package/directory

http://packages.python.org/distribute/setuptools.html#development-mode

2

即使一个软件包没有使用 setuptoolspip 也会对 setup.py 进行一些修改,让它强制使用 setuptools

也许你可以去掉那个 PYTHONPATH 的小技巧,然后直接用 pip install -e /path/to/package 来安装。

撰写回答