是否有可能确定当前脚本是否在virtualenv环境中运行?
当前回答
(编辑)我是这样发现的,你怎么看?(它还返回venv的基本路径,甚至适用于不检查env变量的readthedocs):
import os
import sys
from distutils.sysconfig import get_config_vars
def get_venv_basedir():
"""Returns the base directory of the virtualenv, useful to read configuration and plugins"""
exec_prefix = get_config_vars()['exec_prefix']
if hasattr(sys, 'real_prefix') is False or exec_prefix.startswith(sys.real_prefix):
raise EnvironmentError('You must be in a virtual environment')
return os.path.abspath(get_config_vars()['exec_prefix'] + '/../')
其他回答
这里有很多好的答案,也有一些不太可靠的答案。 以下是概述。
如何不这样做
不要依赖于Python或site-packages文件夹的位置。
如果将这些设置为非标准位置,这并不意味着 你实际上是在一个虚拟的环境中。用户可以拥有多个 Python版本,这些并不总是在你期望的地方。
避免看:
sys.executable sys.prefix pip - v python的
另外,不要检查在这些路径中是否存在venv、.venv或envs。 这将打破具有更独特位置的环境。例如, Pipenv使用哈希值作为其环境的名称。
VIRTUAL_ENV环境变量
virtualenv和venv在激活环境时都会设置环境变量$VIRTUAL_ENV。 参见PEP 405。
您可以在shell脚本中读取该变量,或者使用此Python代码来确定是否设置了该变量。
import os
running_in_virtualenv = "VIRTUAL_ENV" in os.environ
# alternative ways to write this, also supporting the case where
# the variable is set but contains an empty string to indicate
# 'not in a virtual environment':
running_in_virtualenv = bool(os.environ.get("VIRTUAL_ENV"))
running_in_virtualenv = bool(os.getenv("VIRTUAL_ENV"))
问题是,这仅在由activate shell脚本激活环境时才有效。
您可以在不激活环境的情况下启动环境的脚本,因此如果需要考虑这一点,则必须使用不同的方法。
sys.base_prefix
Virtualenv, venv和pyvenv点系统。安装在virtualenv内部的Python的前缀。
同时,将sys. xml文件的原始值修改为sys. xml文件的原始值。Prefix也可用作sys.base_prefix。
我们可以用它来检测我们是否在虚拟环境中。
import sys
# note: Python versions before 3.3 don't have sys.base_prefix
# if you're not in virtual environment
running_in_virtualenv = sys.prefix != sys.base_prefix
回退:sys.real_prefix
现在注意了,virtualenv在版本20之前没有设置sys。Base_prefix但是它设置了sys。real_prefix代替。
所以为了安全起见,请根据hroncok的回答进行检查:
import sys
real_prefix = getattr(sys, "real_prefix", None)
base_prefix = getattr(sys, "base_prefix", sys.prefix)
running_in_virtualenv = (base_prefix or real_prefix) != sys.prefix
水蟒
如果您正在使用Anaconda虚拟环境,请检查 维多利亚·斯图尔特的回答。
最可靠的检查方法是检查sys。Prefix == sys.base_prefix。如果它们相等,则不是在虚拟环境中;如果它们不相等,你就是。在虚拟环境中,sys。Prefix指向虚拟环境,sys. Prefix指向虚拟环境。base_prefix是创建virtualenv的系统Python的前缀。
上面的代码总是适用于python3 stdlib venv和最近的virtualenv(自版本20起)。旧版本的virtualenv使用sys. exe。而不是sys. Real_prefix。Base_prefix(和sys。real_prefix在虚拟环境之外不存在),在Python 3.3和更早的sys. real_prefix中。Base_prefix从未存在过。所以一个完全健壮的检查可以处理所有这些情况,看起来像这样:
import sys
def get_base_prefix_compat():
"""Get base/real prefix, or sys.prefix if there is none."""
return getattr(sys, "base_prefix", None) or getattr(sys, "real_prefix", None) or sys.prefix
def in_virtualenv():
return get_base_prefix_compat() != sys.prefix
如果你只关心支持的Python版本和最新的virtualenv,你可以用sys.base_prefix替换get_base_prefix_compat()。
使用VIRTUAL_ENV环境变量不可靠。它是由virtualenv激活shell脚本设置的,但是virtualenv可以在不激活的情况下使用,直接从virtualenv的bin/(或Scripts)目录运行可执行文件,在这种情况下,$VIRTUAL_ENV将不会被设置。或者一个非virtualenv的Python二进制文件可以在shell中激活virtualenv时直接执行,在这种情况下,$VIRTUAL_ENV可以在一个Python进程中设置,而该进程实际上并没有在该virtualenv中运行。
在windows操作系统中,你会看到这样的东西:
C:\Users\yourusername\virtualEnvName\Scripts>activate
(virtualEnvName) C:\Users\yourusername\virtualEnvName\Scripts>
括号表示您实际处于名为“virtualEnvName”的虚拟环境中。
你可以选择哪个python,看看它是否指向虚拟环境中的那个。
一个潜在的解决方案是:
os.access(sys.executable, os.W_OK)
在我的例子中,我真的只是想检测我是否可以用pip原样安装项目。虽然这可能不是所有情况下的正确解决方案,但请考虑简单地检查您是否具有Python可执行文件位置的写权限。
注意:这适用于所有版本的Python,但如果你使用sudo运行系统Python,也会返回True。下面是一个潜在的用例:
import os, sys
can_install_pip_packages = os.access(sys.executable, os.W_OK)
if can_install_pip_packages:
import pip
pip.main(['install', 'mypackage'])
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if
- 如何在Python中获得所有直接子目录