pip安装路径修改

Author Avatar
patrickcty 9月 22, 2021

出现问题

在跑 PVT 的时候需要安装 mmdet,但是每次都默认安装到 .local 目录下而不是虚拟环境中,导致会和其他环境冲突。查看 sys.path 发现 .local 在虚拟环境之前,导致 pip 默认安装路径不符合预期。

解决

根据这篇博客,pip 安装包默认路径是通过 site.py 来确定的,输入 python -m site,得到以下内容:

sys.path = [
    '/home/sse/anaconda3/envs/pvt',
    '/home/sse/anaconda3/envs/pvt/lib/python37.zip',
    '/home/sse/anaconda3/envs/pvt/lib/python3.7',
    '/home/sse/anaconda3/envs/pvt/lib/python3.7/lib-dynload',
    '/home/sse/.local/lib/python3.7/site-packages',
    '/home/sse/.local/lib/python3.7/site-packages/apex-0.1-py3.7-linux-x86_64.egg',
    '/home/sse/anaconda3/envs/pvt/lib/python3.7/site-packages',
]
USER_BASE: '/home/sse/.local' (exists)
USER_SITE: '/home/sse/.local/lib/python3.7/site-packages' (exists)
ENABLE_USER_SITE: True

可以看出来,当直接 pip install mmdet 的时候,是会安装到 sys.path 第一个目录下的,但是由于当时我使用了 pip install mmdet --user,因此会安装到 USER_SITE 下,也就是 .local。如果需要更改 USER_SITE 和 USER_BASE 配置的话则需要去修改 site.py 文件。

运行 python -m site -help,可以得到 site.py 文件目录,打开之后发现这二者配置如下:

USER_SITE = None
USER_BASE = None

继续往下之后可以发现

def _getuserbase():
    env_base = os.environ.get("PYTHONUSERBASE", None)
    if env_base:
        return env_base

    def joinuser(*args):
        return os.path.expanduser(os.path.join(*args))

    if os.name == "nt":
        base = os.environ.get("APPDATA") or "~"
        return joinuser(base, "Python")

    if sys.platform == "darwin" and sys._framework:
        return joinuser("~", "Library", sys._framework,
                        "%d.%d" % sys.version_info[:2])

    return joinuser("~", ".local")

由于目前所在系统 os.name == “posix”, sys.format == “linux”,因此默认的 base 为 .local,符合预期。如果要让使用了 –user 之后还能下载到虚拟环境下则需要手动添加环境,即修改那两个变量的值:

USER_SITE = '/home/sse/anaconda3/envs/pvt/lib/python3.7/site-packages'
USER_BASE = '/home/sse/anaconda3/envs/pvt'

修改之后保存,再次运行 python -m site,得到结果如下:

sys.path = [
    '/home/sse/anaconda3/envs/pvt',
    '/home/sse/anaconda3/envs/pvt/lib/python37.zip',
    '/home/sse/anaconda3/envs/pvt/lib/python3.7',
    '/home/sse/anaconda3/envs/pvt/lib/python3.7/lib-dynload',
    '/home/sse/anaconda3/envs/pvt/lib/python3.7/site-packages',
]
USER_BASE: '/home/sse/anaconda3/envs/pvt' (exists)
USER_SITE: '/home/sse/anaconda3/envs/pvt/lib/python3.7/site-packages' (exists)
ENABLE_USER_SITE: True

此时结果符合预期,下载的时候也会下载到虚拟环境目录下

总结

使用 pip install 的时候会从 sys.path 获取路径,越靠前优先度越高。

使用 –user 选项下载的时候则会从 site.py 中获取 USER_SITE,如果没有则会根须系统生成一个,然后再安装到这个目录下。

使用虚拟环境的时候没必要使用 –user 选项,因为默认的安装路径就不是系统的路径,不会造成兼容性问题,反而使用了这个选项之后会造成问题。