Python이 virtualenv 내에서 실행 중인지 확인


272

현재 스크립트가 virtualenv 환경 내에서 실행 중인지 확인할 수 있습니까?


2
호기심 때문에 왜 그 사실을 알고 싶습니까?
— Jorge Leitao

1
즉, 쉘 프롬프트를 생성하는 커스텀 스크립트를 작성할 수 있고 venv에 있는지 여부를 알려주는 프롬프트를 원하므로 해당 코드 내에서 외부 도구를 호출하지 않고이를 감지 할 수 있어야합니다. .
— Marcin Orlowski

답변:


227

AFAIK 가장 확실한 확인 방법 (virtualv 및 pip에서 내부적으로 사용되는 방법)은 다음을 확인하는 것입니다 sys.real_prefix.

import sys

if hasattr(sys, 'real_prefix'):
    #...

VIRTUALENV 내부 sys.prefixVIRTUALENV 디렉토리에 포인트 및 sys.real_prefix시스템 파이썬 (보통의 "진짜"접두사 포인트 /usr나 /usr/local또는 일부 등).

virtualenv 외부에는 sys.real_prefix존재하지 않아야합니다.

VIRTUAL_ENV환경 변수를 사용하는 것은 신뢰할 수 없습니다. virtualenv activate쉘 스크립트에 의해 설정 되지만 virtualenv bin/(또는 Scripts) 디렉토리 에서 실행 파일을 직접 실행하여 활성화하지 않고 virtualenv를 사용할 수 있습니다 .이 경우 $VIRTUAL_ENV설정되지 않습니다.


11
이것은 더 이상 Python 3에서 유효하지 않은 것 같습니다.
— Dan P.

49
virtualenv (github.com/pypa/virtualenv)를 사용하는 경우이 답변은 Python 2 또는 Python 3에도 동일합니다. pyvenv ( legacy.python.org/dev/peps/pep-0405 )를 사용하는 경우 virtualenv -Python 3.3 이상에 내장되어 있지만 virtualenv와 동일하지는 않지만 sys.real_prefix 대신 sys.base_prefix를 사용하며 sys.base_prefix는 항상 존재합니다. pyvenv 외부에서는 sys.prefix와 같습니다.
— Carl Meyer 14 년

2
@Kounavi 나는 Windows 버전이 영향을 미칠 것이라고 생각하지 않습니다. 이 답변은 모든 플랫폼에서 virtualenv가 작동하는 방식의 핵심입니다. Windows 2012 컴퓨터에서 virtualenv가 아닌 Python 3 pyvenv를 사용할 수 있습니까? 또는 PATH에 문제가 있으며 실제로 생각할 때 virtualenv에서 실행되고 있지 않습니까?
— Carl Meyer

3
bash는 스크립트를 한 줄PYTHON_ENV=$(python -c "import sys; sys.stdout.write('1') if hasattr(sys, 'real_prefix') else sys.stdout.write('0')")
— 샘 마이어스

2
이 대답은 의외로 쓸모가 없습니다 . 특히이 답변은 일반적인 사용 사례에 대해 잘못된 부정을 반환합니다. 그 나쁜. 대신 아나콘다가 아닌 모든 venvs를 올바르게 감지하는 hroncok 의 정식 업데이트 또는 모든 Anaconda venvs를 올바르게 감지하는 Victoria Stuart 의 정식 응답을 참조하십시오 . ( 이 두 가지 답변을 결합한 사람에 대한 나의 모든 찬성 투표자 )
— Cecil Curry

97

사용해보십시오 pip -V(자본 V)

가상 환경을 실행중인 경우 환경의 위치에 대한 경로가 표시됩니다.


virtualenv주위를 많이 움직 였다면 실패하거나 거짓말을 할 수 있습니다. 거짓말이라면 할 수 있습니다 find /path/to/venv/ -type f -exec sed -ie "s:/old/path/to/venv:/path/to/venv:g" {} \+. 그것이 실패하면 ( "나쁜 마샬 데이터"가 있습니다) .pyc 파일을 닦아야합니다 find /path/to/venv -type f -name "*.pyc" -exec rm {} \+(걱정하지 마십시오, 자동으로 다시 작성됩니다).
— jeremysprofile

방금 Python 3.7을 사용하여 Windows 10에서 이것을 테스트했습니다. 의 기본 설치 ...\lib\site-packages에서 pip 위치를 인쇄 합니다 %PATH%. 따라서이 경우 거짓 긍정을 반환합니다.
— JamesThomasMoon1979

71

이것은 Carl Meyer의 대답에 대한 개선입니다 . 그것은 작동 VIRTUALENV 파이썬 3과 2 및도에 대한 venv의 파이썬 3 모듈 :

import sys


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

sys.real_prefix비어 있지 않은 커버링 venv sys.base_prefix와 동등한 virtualenv 커버를 확인합니다 sys.prefix.

다음과 같은 기능을 사용하는 스크립트를 고려하십시오.

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 

4
Python 3.3은 더 이상 대부분의 Python 3 프레임 워크 및 응용 프로그램에서 유지 관리하거나 지원하지 않기 때문에 이제이 함수는 사소한 한 줄짜리로 줄어 듭니다 def is_venv(): return hasattr(sys, 'real_prefix') or sys.base_prefix != sys.prefix. 그냥 말해
— 세실 커리

안타깝게도 pipenv생성 된 가상 환경에서는 작동하지 않는 것 같습니다 .
— dragon788

46

$VIRTUAL_ENV환경 변수를 확인하십시오 .

$VIRTUAL_ENV환경 변수는 활성 가상 환경에서 가상 환경의 디렉토리 때를 포함한다.

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

deactivate가상 환경 을 실행하고 나면 $VIRTUAL_ENV변수가 지워집니다. KeyError환경 변수가 설정되지 않았기 때문에 파이썬은 a를 발생 시킵니다.

>>> 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 스크립트 외부의 셸에서 수행 할 수도 있습니다.


1
이것은 virtualenvvirtualenv와 virtualenv 모두에 대해 작동합니다 venv.
— florisla

@verboze : 그것이 해야하는 것처럼, 맞습니까? 비활성화 된 virtualenv는 사용자 스크립트가 실행 되지 않음을 의미합니다 .
— MestreLion

이것은 virtualenv가 활성화되어 있는지 확인하지만 반드시 Python 프로세스가 해당 virtualenv에서 실행되었음을 의미하지는 않습니다.
— erb

20

http://www.python.org/dev/peps/pep-0405/#specification 의 virtualenv pep에 따르면 os.environ [ 'VIRTUAL_ENV'] 대신 sys.prefix를 사용할 수 있습니다.

sys.real_prefix가 내 virtualenv에 없으며 sys.base_prefix와 동일합니다.


8
virtualenv는 모든 Python 버전 ( github.com/pypa/virtualenv ) 에서 작동하는 독립형 프로젝트입니다 . 당신이 연결 한 PEP는 pyvenv를위한 것이며, virtualenv를 기반으로하지만 다르게 구현되고 (더 나은) 파이썬 3.3+에 내장되어 있습니다. 이 질문은 pyvenv가 아닌 virtualenv에 관한 것입니다. 당신은 pyvenv에가 없다는 것이 맞습니다 sys.real_prefix.
— Carl Meyer

5
이 답변을 사용하여 bash에서 감지하는 좋은 방법은 실행 env |grep VIRTUAL_ENV |wc -l 하는 것입니다. venv에 있으면 1을, 그렇지 않으면 0을 반환합니다.
— LISTERINE

3
쉘에 있다면 간단히 사용 [[ -n $VIRTUAL_ENV ]] && echo virtualenv하거나 [[ -z $VIRTUAL_ENV ]] && echo not virtualenv필요에 따라 사용할 수 있습니다 .
— Six

9

내부 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")}')

1
이것이 최고의 크로스 플랫폼 (Windows / Unix) 방식입니다.
— Adi Unnithan

지금까지 이것은 크로스 플랫폼, python 2 및 python 3 호환 방식입니다. 감사.
— RJ

9

여기에는 여러 가지 좋은 답변이 있으며 덜 견고한 답변이 있습니다. 개요는 다음과 같습니다.

하지 않는 방법

파이썬이나 site-packages폴더 의 위치에 의존하지 마십시오 .

이러한 위치가 비표준 위치로 설정되어 있어도 실제로 가상 환경에있는 것은 아닙니다 . 사용자는 둘 이상의 Python 버전을 설치할 수 있으며 항상 원하는 위치에있는 것은 아닙니다.

다음을 보지 마십시오.

  • sys.executable
  • sys.prefix
  • pip -V
  • which python

또한,의 존재를 확인하지 않는 venv, .venv또는 envs이러한 경로 중 하나입니다. 위치가 더 고유 한 환경에서는 문제가 발생합니다. 예를 들어 Pipenv 는 해시 값을 해당 환경의 이름으로 사용합니다.

VIRTUAL_ENV 환경 변수

모두 virtualenv와 venv환경 변수를 설정 $VIRTUAL_ENV하는 환경을 활성화 할 때. PEP 405를 참조하십시오 .

쉘 스크립트에서이 변수를 읽거나이 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.

환경 을 활성화하지 않고 환경의 스크립트 를 시작할 수 있으므로 우려되는 경우 다른 방법을 사용해야합니다.

sys.base_prefix

virtualenv, venv및 pyvenv포인트 sys.prefix당신이 예상하는대로 파이썬은 내부 VIRTUALENV의 설치.

동시에의 원래 값 sys.prefix도로 사용할 수 있습니다 sys.base_prefix.

이를 사용하여 virtualenv에 있는지 감지 할 수 있습니다.

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 가상 환경을 사용하는 경우 Victoria Stuart의 답변을 확인하십시오 .


OP는 "어떻게하지 않습니까?"가 아니라 "어떻게해야합니까?" 이 답변은 과잉입니다. 그것은 질문의 정신을 넘어서고 너무 많은 변형으로 대답을 모호하게합니다. 답변을 가능한 한 단순하게 유지하고 질문에 직접 답변하십시오.
— Rich Lysakowski PhD

여기에 여러 답변을 요약하고 특정 상황에 적합한 답변을 제공합니다. 원래 질문은 이러한 기술 중 하나를 '최고의'기술로 선택할 수있는 충분한 컨텍스트를 제공하지 않습니다. 그것은 간단하지 않습니다.
— florisla

1
sys.base_prefix 섹션에서 테스트를 수행해서는 안됩니다.running_in_virtualenv = sys.*base_*prefix != sys.prefix
— usonianhorizon

@usonianhorizon 사실, 감사합니다!
— florisla

@florisia 감사합니다! 응용 프로그램 배포를 위해 virtualenvwrapper에서 내장 venv로 전환하는 중이며 설명에 따라 템플릿을 제공하는 방법이 설명되었습니다. 나는 if hasattr(sys, 'real_prefix'):더 이상 효과가없는 테스트 에만 의존하고있었습니다 .
— usonianhorizon

8

which python가상 환경에서 가상 환경을 가리키고 있는지 확인할 수 있습니다 .


1
whichWindows에서는 기본적으로 사용할 수 없습니다. where대신 Windows에서 사용하거나 whichcraft를 사용할 수 있습니다 . 또는을보십시오 sys.executable. 그러나 여전히 더 좋은 방법이 있습니다.
— florisla

5
  • 2019 년 11 월 업데이트 됨 (첨부).

나는 일상적으로 여러 Anaconda 설치 가상 환경 (venv)을 사용합니다. 이 코드 스 니펫 / 예를 사용하면 venv (또는 시스템 환경)에 있는지 여부를 판별하고 스크립트에 특정 venv를 요구할 수도 있습니다.

Python 스크립트에 추가 (코드 스 니펫) :

# ----------------------------------------------------------------------------
# Want script to run in Python 3.5 (has required installed OpenCV, imutils, ... packages):
import os

# First, see if we are in a conda venv { py27: Python 2.7 | py35: Python 3.5 | tf: TensorFlow | thee : Theano }
try:
   os.environ["CONDA_DEFAULT_ENV"]
except KeyError:
   print("\tPlease set the py35 { p3 | Python 3.5 } environment!\n")
   exit()

# If we are in a conda venv, require the p3 venv:
if os.environ['CONDA_DEFAULT_ENV'] != "py35":
    print("\tPlease set the py35 { p3 | Python 3.5 } environment!\n")
    exit()

# See also:
# Python: Determine if running inside virtualenv
# http://stackoverflow.com/questions/1871549/python-determine-if-running-inside-virtualenv  
# [ ... SNIP! ... ]

예:

$ p2
  [Anaconda Python 2.7 venv (source activate py27)]

(py27) $ python  webcam_.py
    Please set the py35 { p3 | Python 3.5 } environment!

(py27) $ p3
  [Anaconda Python 3.5 venv (source activate py35)]

(py35) $ python  webcam.py -n50

    current env: py35
    processing (live): found 2 faces and 4 eyes in this frame
    threaded OpenCV implementation
    num_frames: 50
    webcam -- approx. FPS: 18.59
    Found 2 faces and 4 eyes!
(py35) $

업데이트 1-bash 스크립트에서 사용 :

bash 스크립트 (예 : 특정 가상 환경에서 실행해야하는 스크립트)에서도이 방법을 사용할 수 있습니다. 예제 (bash 스크립트에 추가) :

if [ $CONDA_DEFAULT_ENV ]        ## << note the spaces (important in BASH)!
    then
        printf 'venv: operating in tf-env, proceed ...'
    else
        printf 'Note: must run this script in tf-env venv'
        exit
fi

업데이트 2 [2019 년 11 월]

원래 게시물 이후 Anaconda venv에서 옮겼습니다 (Python 자체는 viz-a-viz 가상 환경으로 발전했습니다 ).

이 문제를 다시 검토하면 특정 Python 가상 환경 (venv)에서 작동 중인지 테스트하기 위해 삽입 할 수있는 업데이트 된 Python 코드가 있습니다.

import os, re
try:
    if re.search('py37', os.environ['VIRTUAL_ENV']):
        pass
except KeyError:
    print("\n\tPlease set the Python3 venv [alias: p3]!\n")
    exit()

다음은 설명 코드입니다.

[victoria@victoria ~]$ date; python --version
  Thu 14 Nov 2019 11:27:02 AM PST
  Python 3.8.0

[victoria@victoria ~]$ python
  Python 3.8.0 (default, Oct 23 2019, 18:51:26) 
  [GCC 9.2.0] on linux
  Type "help", "copyright", "credits" or "license" for more information.

>>> import os, re

>>> re.search('py37', os.environ['VIRTUAL_ENV'])
<re.Match object; span=(20, 24), match='py37'>

>>> try:
...     if re.search('py37', os.environ['VIRTUAL_ENV']):
...       print('\n\tOperating in Python3 venv, please proceed!  :-)')
... except KeyError:
...     print("\n\tPlease set the Python3 venv [alias: p3]!\n")
... 

    Please set the Python3 venv [alias: p3]!

>>> [Ctrl-d]
  now exiting EditableBufferInteractiveConsole...

[victoria@victoria ~]$ p3
  [Python 3.7 venv (source activate py37)]

(py37) [victoria@victoria ~]$ python --version
  Python 3.8.0

(py37) [victoria@victoria ~]$ env | grep -i virtual
  VIRTUAL_ENV=/home/victoria/venv/py37

(py37) [victoria@victoria ~]$ python
  Python 3.8.0 (default, Oct 23 2019, 18:51:26) 
  [GCC 9.2.0] on linux
  Type "help", "copyright", "credits" or "license" for more information.

>>> import os, re
>>> try:
...     if re.search('py37', os.environ['VIRTUAL_ENV']):
...       print('\n\tOperating in Python3 venv, please proceed!  :-)')
... except KeyError:
...     print("\n\tPlease set the Python3 venv [alias: p3]!\n")
... 

    Operating in Python3 venv, please proceed!  :-)
>>> 

3

가장 쉬운 방법은 다음을 실행하는 것입니다. which python, virtualenv에 있으면 전역이 아닌 파이썬을 가리 킵니다.


1
나는 이것이 실제로 "현재 스크립트"에 관한 질문에 대답한다고 생각하지 않는다. 그러나 이것은 내 질문에 대한 대답입니다. "명령 줄에서 가상 환경에 있는지 어떻게 알 수 있습니까?"
— ukrutt

1

(편집) 그 방법을 찾았습니다. 어떻게 생각하십니까? (또한 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'] + '/../')

0

이미 여기에 게시 된 훌륭한 방법이 많이 있지만 하나만 추가하면됩니다.

import site
site.getsitepackages()

pip패키지 가 설치된 위치를 알려줍니다 .


이것은 파이썬이 가상 환경에서 실행되고 있는지 여부를 알려주지 않습니다.
— florisla

@florisla 좀 더 자세히 설명해 주시겠습니까? 경우 site.getsitepackages()출력 시스템 일이 아니다 디렉토리에, 당신은 당신이 가상 환경에있어 추론 할 수 있습니다.
— flow2k

여러 위치에 Python을 설치할 수 있습니다. 예를 들어, Windows에서는 '시스템'Python 및 WinPython 배포와 Conda 기반 Python을 설치할 수 있습니다. 이들은 모두 다른 사이트 패키지 폴더를 갖지만 반드시 a에 의해 생성되거나 사용되는 것은 아닙니다 virtualenv.
— florisla

@florisla 좋은 지적-방금 이것이 (venv 또는 not)이 질문이 묻는 것임을 보았습니다 (다른 질문에 대해 비슷한 답변을 작성했습니다). 나는 이것이 당신이 venv에 있는지 아닌지에 대한 확실한 대답을 줄 수는 없지만 어떤 파이썬이나 어떤 venv것을 사용하고 있는지 알려주는 데 도움이 될 수 있음에 동의합니다 .
— flow2k

-1

방탄은 아니지만 UNIX 환경의 경우 다음과 같은 간단한 테스트입니다.

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

나를 위해 잘 작동합니다. 그런 다음 기존의 일부 속성을 테스트하는 것이 더 간단하며 어쨌든 venv directory 이름을 지정해야합니다 venv.


-1

Windows OS에서는 다음과 같은 내용이 표시됩니다.

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

괄호는 실제로 "virtualEnvName"이라는 가상 환경에 있음을 의미합니다.


당신과 나는 'virtualEnvName'을 잘 읽을 수 있습니다. 그러나 문제는 파이썬 모듈이 이것을 어떻게 읽을 수 있는지입니다.
— florisla

-1

잠재적 인 솔루션입니다 :

os.access(sys.executable, os.W_OK)

필자의 경우 실제로 pip로 항목을 설치할 수 있는지 감지하고 싶었습니다. 모든 경우에 적합한 솔루션은 아니지만 Python 실행 파일의 위치에 대한 쓰기 권한이 있는지 간단히 확인하십시오.

참고 : 이것은 모든 버전의 Python에서 작동하지만 True시스템 Python을 사용하여 실행하면 반환 합니다 sudo. 잠재적 사용 사례는 다음과 같습니다.

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'])

-1

이것은 오래된 질문이지만, 위의 너무 많은 예가 지나치게 복잡합니다.

단순하게 유지 : (Windows 10의 Jupyter Notebook 또는 Python 3.7.1 터미널)


import sys
print(sys.executable)```

# example output: >> `C:\Anaconda3\envs\quantecon\python.exe`

OR 
```sys.base_prefix```

# Example output: >> 'C:\\Anaconda3\\envs\\quantecon'

envs해당 경로에 존재하는지 확인하기 위해 로직을 추가 하면 아나콘다에서 virtualenv또는 로 이동할 때 작동이 중지됩니다 pipenv.
— florisla

Florisla, 귀하는 제한 범위 내에서 저에게 적합한 답변을 제공 한 지 거의 3 개월이 지나서 "하지 않는 방법"에 대한 답변을 제공했습니다 (virtuenv와 pipenv간에 이동하지 않음). 자신의 모습을 더 좋게 보이기 위해 다른 사람들의 대답을 공감하는 것은 나쁜 스포츠입니다.
— Rich Lysakowski PhD

부자, 당신을 위해 일하는 것은 다른 사람들을 위해 일하지 않을 수 있습니다. 원본 포스터에서는 작동하지 않을 수도 있습니다.
— florisla
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.