如何在保留用户站点包的同时避免在Python的sys.path中有当前目录?

2024-05-20 10:59:38 发布

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

用户可以在包含自己的Python脚本的目录中执行MyPython应用程序。如果这些脚本中的任何一个的名称与我的程序使用的库模块冲突(甚至与我的模块名称冲突),则所有脚本都会出现一条没有帮助的错误消息

我知道Python(从3.4开始)有-I开关,这使得导入机器忽略当前目录(即""不会被添加到sys.path)。这几乎可以解决我的问题,但它的副作用是忽略用户站点包

我知道我可以在我的程序加载后调整sys.path,但是如果用户(无意中)隐藏了我程序的主模块,这将不会有帮助

我可以让Python忽略当前目录,但同时给我用户站点包吗


Tags: 模块path用户程序目录脚本名称机器
1条回答
网友
1楼 · 发布于 2024-05-20 10:59:38

您可以通过调用site.addusersitepackages(None)重新启用用户站点路径(None的简单意思是:检查现有的sys.path定义以避免添加重复的路径):

import site
import sys

if sys.flags.no_user_site and sys.prefix == sys.base_prefix:
    # python -s or python -I has disabled user sites, and this is not a virtualenv
    site.ENABLE_USER_SITE = True
    site.addusersitepackages(None)

快速演示:

>>> import site, sys, os.path
>>> user_site = os.path.expanduser(f"~/.local/lib/python{sys.version_info.major}.{sys.version_info.minor}/site-packages")
>>> user_site in sys.path
False
>>> sys.flags.no_user_site
1
>>> site.ENABLE_USER_SITE = True
>>> site.addusersitepackages(None)
>>> user_site in sys.path
True

虽然site.addusersitepackages()未记录,但它是site.main()的关键组成部分,是also quite simple。如果您觉得无法依赖它的持续存在,请按如下方式重新实现:

import os.path
import site

def addusersitepackages():
    user_site = site.getusersitepackages()

    if site.ENABLE_USER_SITE and os.path.isdir(user_site):
        site.addsitedir(user_site)

这个版本完全省略了known_paths参数,并且只使用记录在案的site属性和函数:^{}^{}^{}

或者,将上述内容折叠到代码中以启用用户站点目录,包装为函数:

import os.path
import site
import sys

def ensure_usersitepackages():
    if sys.flags.no_user_site and sys.prefix == sys.base_prefix:
        # if python -s or python -I has disabled user sites, and this 
        # is not a virtualenv, explicitly enable user sites anyway.
        site.ENABLE_USER_SITE = True
        user_site = site.getusersitepackages()
        if os.path.isdir(user_site):
            site.addsitedir(user_site)

相关问题 更多 >