如何判断Python是否在虚拟环境中运行?

518 投票
19 回答
390702 浏览
提问于 2025-04-15 16:49

有没有办法判断当前的脚本是否在一个虚拟环境(virtualenv)中运行?

19 个回答

101

检查一下 $VIRTUAL_ENV 这个环境变量。

当你在一个活跃的虚拟环境中时,$VIRTUAL_ENV 这个环境变量会包含虚拟环境的目录。

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

一旦你运行 deactivate 命令或者离开虚拟环境,$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 脚本之外,在命令行中进行。

299

试试用 pip -V(注意大写的V)

如果你在使用虚拟环境,这个命令会显示这个环境的路径。

354

判断你是否在虚拟环境中,最可靠的方法是比较 sys.prefixsys.base_prefix 这两个值。如果它们相等,说明你不在虚拟环境中;如果不相等,那你就是在虚拟环境里。在虚拟环境中,sys.prefix 指向虚拟环境的目录,而 sys.base_prefix 指向用来创建这个环境的 Python 解释器。

这方面的详细信息可以在 虚拟环境的工作原理 中找到:

只需检查 sys.prefix != sys.base_prefix 就可以判断当前的解释器是否在虚拟环境中运行。

这个方法适用于 Python 标准库中的 venvvirtualenv(从版本 20 开始):

def in_venv():
    return sys.prefix != sys.base_prefix

旧版本的 virtualenv 使用 sys.real_prefix 来代替 sys.base_prefix,而且 sys.real_prefix 在虚拟环境外是不存在的。在 Python 3.3 及之前的版本中,sys.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 sys.prefix != get_base_prefix_compat()

使用 VIRTUAL_ENV 环境变量并不可靠。这个变量是由虚拟环境的 activate 脚本设置的,但你可以在不激活虚拟环境的情况下,直接运行虚拟环境的 bin/(或 Scripts)目录中的可执行文件,这样 $VIRTUAL_ENV 就不会被设置。或者,你也可以在激活虚拟环境的情况下,直接运行一个非虚拟环境的 Python 可执行文件,这样 $VIRTUAL_ENV 可能会在一个实际上并不在那个虚拟环境中的 Python 进程中被设置。

撰写回答