是否有可能确定当前脚本是否在virtualenv环境中运行?


当前回答

检查$VIRTUAL_ENV环境变量。

在活动的虚拟环境中,$VIRTUAL_ENV环境变量包含虚拟环境的目录。

>>> import os
>>> os.environ['VIRTUAL_ENV']
'/some/path/project/venv'

一旦执行deactivate / leave虚拟环境,$VIRTUAL_ENV变量将被清除/空。Python将引发一个KeyError,因为环境变量未设置。

>>> import os
>>> os.environ['VIRTUAL_ENV']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/os.py", line 678, in __getitem__
    raise KeyError(key) from None
KeyError: 'VIRTUAL_ENV'

当然,这些相同的环境变量检查也可以在Python脚本之外的shell中完成。

其他回答

在windows操作系统中,你会看到这样的东西:

C:\Users\yourusername\virtualEnvName\Scripts>activate
(virtualEnvName) C:\Users\yourusername\virtualEnvName\Scripts>

括号表示您实际处于名为“virtualEnvName”的虚拟环境中。

如果你正在使用水蟒,这里是解决方案。该命令列出所有可发现的环境

conda info --envs

这是对卡尔·迈耶的公认答案的改进。它可以与Python 3和2中的virtualenv一起工作,也可以与Python 3中的venv模块一起工作:

import sys


def is_venv():
    return (hasattr(sys, 'real_prefix') or
            (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix))

检查sys。Real_prefix覆盖了virtualenv,非空的sys。带sys的Base_prefix。前缀覆盖venv。

考虑一个像这样使用函数的脚本:

if is_venv():
    print('inside virtualenv or venv')
else:
    print('outside virtualenv or venv')

以及下面的调用:

$ python2 test.py 
outside virtualenv or venv

$ python3 test.py 
outside virtualenv or venv

$ python2 -m virtualenv virtualenv2
...
$ . virtualenv2/bin/activate
(virtualenv2) $ python test.py 
inside virtualenv or venv
(virtualenv2) $ deactivate

$ python3 -m virtualenv virtualenv3
...
$ . virtualenv3/bin/activate
(virtualenv3) $ python test.py 
inside virtualenv or venv
(virtualenv3) $ deactivate 

$ python3 -m venv venv3
$ . venv3/bin/activate
(venv3) $ python test.py 
inside virtualenv or venv
(venv3) $ deactivate 

最可靠的检查方法是检查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中运行。

这里已经发布了很多很棒的方法,但只需要再添加一个:

import site
site.getsitepackages()

告诉您PIP安装包的位置。