如何避免在Python中使用当前目录';s sys.path,同时保留用户站点包?
用户可以在包含自己的Python脚本的目录中执行MyPython应用程序。如果这些脚本中的任何一个的名称与我的程序使用的库模块冲突(甚至与我的模块名称冲突),则所有脚本都会出现一条没有帮助的错误消息 我知道Python(从3.4开始)有如何避免在Python中使用当前目录';s sys.path,同时保留用户站点包?,python,command-line,Python,Command Line,用户可以在包含自己的Python脚本的目录中执行MyPython应用程序。如果这些脚本中的任何一个的名称与我的程序使用的库模块冲突(甚至与我的模块名称冲突),则所有脚本都会出现一条没有帮助的错误消息 我知道Python(从3.4开始)有-I开关,这使得导入机器忽略当前目录(即“不会被添加到sys.path)。这几乎可以解决我的问题,但它的副作用是忽略用户站点包 我知道我可以在我的程序加载后调整sys.path,但是如果用户(无意中)隐藏了我程序的主模块,那就没用了 我可以让Python忽略当前目
-I
开关,这使得导入机器忽略当前目录(即“
不会被添加到sys.path
)。这几乎可以解决我的问题,但它的副作用是忽略用户站点包
我知道我可以在我的程序加载后调整sys.path
,但是如果用户(无意中)隐藏了我程序的主模块,那就没用了
我可以让Python忽略当前目录,但同时给我用户站点包吗?您可以通过调用
site.addusersitepackages(None)
重新启用用户站点路径(None)(None
的简单意思是:检查现有的sys.path
定义以避免添加重复路径):
快速演示:
>>> 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()
的一个关键组件。如果您觉得无法依赖它的持续存在,请按如下方式重新实现:
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)
此版本完全省略了已知路径
参数,仅使用文档化的站点
属性和函数:,和
或者,将上述内容折叠到代码中以启用用户站点目录,包装为函数:
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)
非常感谢。你知道为什么
site
的API文档中没有提到addusersitepackages
?它看起来不像是一个私有函数。它是否保证存在于CPython的所有安装中(比如说3.9和更高版本)?@Aivar:它是一个内部站点
功能,没有记录,因为没有人认为它需要记录,猜测一下。我不能告诉您它是否保证在以后的Python版本中存在,因为我没有水晶球,但它存在于迄今为止的所有Python 3.x版本中(包括3.10a6)。@Aivar我为addusersitepackages()
添加了一个内联实现,以防您仍然担心它的长期可行性。
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)