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 환경 변수

모두 virtualenvvenv환경 변수를 설정 $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, venvpyvenv포인트 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.