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


当前回答

你可以选择哪个python,看看它是否指向虚拟环境中的那个。

其他回答

检查你的Virtualenv内部:

import os

if os.getenv('VIRTUAL_ENV'):
    print('Using Virtualenv')
else:
    print('Not using Virtualenv')

您还可以获得有关您的环境的更多数据:

import sys
import os

print(f'Python Executable: {sys.executable}')
print(f'Python Version: {sys.version}')
print(f'Virtualenv: {os.getenv("VIRTUAL_ENV")}')

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

它不是万无一失的,但是对于UNIX环境的简单测试,比如

if run("which python3").find("venv") == -1:
    # something when not executed from venv

对我来说很好。这比测试现有的某些属性要简单得多,无论如何,您应该将venv目录命名为venv。

这是对卡尔·迈耶的公认答案的改进。它可以与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 

你可以选择哪个python,看看它是否指向虚拟环境中的那个。