Python'un virtualenv içinde çalışıp çalışmadığını belirleme


272

Geçerli betiğin bir sanal ortam içinde çalışıp çalışmadığını belirlemek mümkün müdür?


2
Meraktan, neden bilmek istiyorsun?
Jorge Leitao

1
örneğin, kabuğunuz için bilgi istemi üreten özel komut dosyası yazabilmek ve bu istemin venv'de olup olmadığınızı belirtmesini istiyorsanız, bu kodun içinden, en iyi harici araçları çağırarak bunu tespit etmek istersiniz. .
Marcin Orlowski

Yanıtlar:


227

AFAIK bunu kontrol etmenin en güvenilir yolu (ve sanal olarak sanal olarak ve pip'te dahili olarak kullanılan yöntem) aşağıdakilerin varlığını kontrol etmektir sys.real_prefix:

import sys

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

Bir virtualenv içinde, sys.prefixVirtualenv dizinine noktaları ve sys.real_prefixsistemin Python (genellikle "gerçek" öneki işaret /usrya /usr/localya da bazı tür).

Bir virtualenv dışında, sys.real_prefixolmamalıdır.

VIRTUAL_ENVOrtam değişkenini kullanmak güvenilir değildir. Virtualenv activatekabuk betiği tarafından ayarlanır , ancak virtualenv'in bin/(veya Scripts) dizininden bir yürütülebilir dosyayı doğrudan çalıştırarak etkinleştirilmeden bir virtualenv kullanılabilir , bu durumda $VIRTUAL_ENVayarlanmaz.


11
Bu artık Python 3'te geçerli görünmüyor.
Dan P.

49
Virtualenv (github.com/pypa/virtualenv) kullanıyorsanız, bu cevap Python 2 veya Python 3 için aynı şekilde doğrudur. Pyvenv ( legacy.python.org/dev/peps/pep-0405 ) kullanıyorsanız, bir virtualenv -Python 3.3+ (ancak virtualenv ile aynı şey değil) içine yerleştirilmiş, o zaman sys.real_prefix yerine sys.base_prefix kullanır ve sys.base_prefix her zaman vardır; bir pyvenv dışında sys.prefix değerine eşittir.
Carl Meyer

2
@Kounavi Windows sürümünün herhangi bir etkisi olacağını düşünmüyorum. Bu cevap, virtualenv'in herhangi bir platformda nasıl çalıştığının temel bir parçasıdır. Windows 2012 makinesinde virtualenv yerine Python 3 pyvenv kullanmanız mümkün müdür? Ya da PATH ile ilgili bir şeyler oluyor ve aslında sandığınızı düşündüğünüzde sanal ortamda çalışmıyorsunuz?
Carl Meyer

3
Bh komut dosyaları için tek satırlıPYTHON_ENV=$(python -c "import sys; sys.stdout.write('1') if hasattr(sys, 'real_prefix') else sys.stdout.write('0')")
Sam Myers

2
Bu cevap modası geçmiş, şaşırtıcı değil. Özellikle, bu cevap yaygın kullanım durumları için yanlış negatifleri döndürür. Bu kötü. Bunun yerine, ya bakınız hroncok 'ın doğru olmayan tüm Anaconda tespit yetkili güncelleme venvs veya Victoria Stuart ' ın doğru tüm Anaconda tespit Yetkisiz yanıt venvs . ( Bu iki yanıtı kimin birleştirdiğine dair tüm görüşlerim. )
Cecil Curry

97

Kullanmayı deneyin pip -V(büyük harf V'ye dikkat edin)

Sanal env çalıştırıyorsanız. env.'nin konumuna giden yolu gösterecektir.


virtualenvEtrafında çok hareket ettiysen , bu başarısız olabilir veya sana yalan söyleyebilir. Eğer yalan söylüyorsa, yapabilirsin find /path/to/venv/ -type f -exec sed -ie "s:/old/path/to/venv:/path/to/venv:g" {} \+. Başarısız olursa ("kötü mareşal verilerim var") .pyc dosyalarını silmeniz gerekir find /path/to/venv -type f -name "*.pyc" -exec rm {} \+(endişelenmeyin, otomatik olarak yeniden oluşturulurlar).
jeremysprofile

Bunu Windows 10'da Python 3.7 ile test ettim. Bu varsayılan pip yeri yüklemek yazdırır ...\lib\site-packagesiçinde %PATH%. Bu durumda yanlış bir pozitif geri dönecektir.
JamesThomasMoon1979

71

Bu, Carl Meyer tarafından kabul edilen cevabın iyileştirilmesidir . Python 3 ve 2 ve ayrıca Python 3'teki venv modülü için virtualenv ile çalışır :

import sys


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

Onay sys.real_prefixkapakları Virtualenv, boş olmayan eşitliği sys.base_prefixile sys.prefixkapaklar venv.

Bu işlevi kullanan bir komut dosyası düşünün:

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

Ve aşağıdaki çağrı:

$ 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 artık tutulan veya desteklenen en Python 3 çerçeveler ve uygulamalar tarafından olduğu için, bu fonksiyonu artık önemsiz bir astara azaltır: def is_venv(): return hasattr(sys, 'real_prefix') or sys.base_prefix != sys.prefix. Sadece söylüyorum'.
Cecil Curry

Ne yazık ki bu pipenvoluşturulan sanal ortamlarla çalışmıyor gibi görünüyor .
dragon788

46

$VIRTUAL_ENVOrtam değişkenini kontrol edin .

$VIRTUAL_ENVOrtam değişkeni aktif sanal ortamda sanal ortamın dizinini zaman içerir.

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

deactivateSanal ortamı çalıştırdığınızda / bıraktığınızda, $VIRTUAL_ENVdeğişken silinir / boşaltılır. Python KeyError, ortam değişkeni ayarlanmadığı için bir yükseltecektir .

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

Bu aynı ortam değişkeni kontrolleri elbette Python betiğinin dışında kabukta da yapılabilir.


1
Bu, hem bir virtualenvsanal ekran hem de bir sanal ekran için çalışır venv.
florisla

@verboze: olması gerektiği gibi, değil mi? Bir kullanıcı komut dosyası olduğu Virtualenv araçları devre dışı değil birinde çalışan.
MestreLion

Bu, bir virtualenv'in etkinleştirilip etkinleştirilmediğini kontrol eder, ancak bu, çalışan Python işleminin o virtualenv'den olduğu anlamına gelmez.
erb

20

En Virtualenv pep göre http://www.python.org/dev/peps/pep-0405/#specification yapmak yerine [ 'VIRTUAL_ENV'] os.environ sys.prefix kullanabilirsiniz.

sys.real_prefix sanal arayüzümde mevcut değil ve sys.base_prefix ile aynı.


8
virtualenv, herhangi bir Python sürümünde ( github.com/pypa/virtualenv ) çalışan bağımsız bir projedir . Bağlantı kurduğunuz PEP, virtualenv tabanlı ancak farklı (daha iyi) uygulanan ve Python 3.3+ için yerleşik olan pyvenv içindir. Bu soru pyvenv ile değil, virtualenv ile ilgilidir. Bir pyvenv'de hayır olmadığı doğru sys.real_prefix.
Carl Meyer

5
Bu cevabı kullanarak env |grep VIRTUAL_ENV |wc -l bash'den tespit etmenin güzel bir yolu çalıştırmaktır: bir venv ise 1 veya değilse 0 döndürür.
LISTERINE

3
Eğer bir kabuğun içindeyseniz [[ -n $VIRTUAL_ENV ]] && echo virtualenvveya [[ -z $VIRTUAL_ENV ]] && echo not virtualenvihtiyaçlarınıza bağlı olarak kullanabilirsiniz .
Altı

9

İçinizdeki Virtualenv'in olup olmadığını kontrol etmek için:

import os

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

Ayrıca ortamınız hakkında daha fazla veri alabilirsiniz:

import sys
import os

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

1
Bu en iyi platformlar arası (Windows / Unix) yaklaşımdır.
Adi Unnithan

Şimdiye kadar, bu sadece çapraz platform, python 2 ve python 3 uyumlu bir yoldur. Teşekkürler.
RJ

9

Burada çok sayıda iyi yanıt var ve daha az sağlam cevaplar var. İşte bir genel bakış.

Nasıl yapılmaz

Python'un veya site-packagesklasörün konumuna güvenmeyin .

Bu standart dışı konumlara ayarlanır, bu mu değil bir sanal ortamda aslında olduğun anlamına. Kullanıcıların birden fazla Python sürümü yüklü olabilir ve bunlar her zaman beklediğiniz yerde değildir.

Şuna bakmaktan kaçının:

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

Ayrıca mevcut olup olmadığını kontrol yok venv, .venvya da envsbu yolların herhangi birinde. Bu, daha benzersiz bir konuma sahip ortamlar için kırılacaktır. Örneğin Pipenv , ortamlarının adı olarak karma değerleri kullanır.

VIRTUAL_ENV Çevre değişkeni

Hem virtualenvve venvortam değişkeni ayarlamak $VIRTUAL_ENVbir ortam aktive olduğunda. Bkz. PEP 405 .

Bu değişkeni kabuk komut dosyalarında okuyabilir veya ayarlanıp ayarlanmadığını belirlemek için bu Python kodunu kullanabilirsiniz.

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"))

Sorun şu ki, bu yalnızca ortam kabuk betiği tarafından etkinleştirildiğinde çalışır activate.

Ortamı etkinleştirmeden ortamın komut dosyalarını başlatabilirsiniz , bu nedenle endişe ediyorsanız farklı bir yöntem kullanmanız gerekir.

sys.base_prefix

virtualenv, venvVe pyvenvnokta sys.prefixbeklediğiniz gibi Python için içeri virtualenv kurulu.

Aynı zamanda, orijinal değeri sys.prefixolarak da kullanılabilir sys.base_prefix.

Bunu bir sanal ortamda olup olmadığımızı tespit etmek için kullanabiliriz.

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

Geri çekil: sys.real_prefix

Şimdi dikkat edin, virtualenvsürüm 20 başlamadan önce yerine sys.base_prefixayarlandı sys.real_prefix.

Güvende olmak için, ikisini de hroncok'un cevabında önerildiği gibi kontrol edin :

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

anakonda

Anaconda sanal ortamlarını kullanıyorsanız, Victoria Stuart'ın cevabını kontrol edin .


OP, "Nasıl YAPILMAZ?" Değil, "Nasıl yapılır?" Sorusunu soruyor. Bu cevap aşırı. Sorunun ruhunun ötesine geçer ve cevabı çok fazla varyasyonla karıştırır. Lütfen cevaplarınızı mümkün olduğunca basit tutun ve soruyu doğrudan yanıtlayın.
Zengin Lysakowski Doktora

Burada birden fazla yanıtı özetliyorum ve hangisinin belirli durumlar için doğru olabileceği konusunda tavsiyelerde bulunuyorum. Orijinal soru, bu tekniklerden birini 'en iyi' olarak seçmek için yeterli bağlam sağlamaz - sadece o kadar basit değil.
florisla

1
Sys.base_prefix bölümünde, test şu şekilde olmamalıdır:running_in_virtualenv = sys.*base_*prefix != sys.prefix
usonianhorizon

@usonianhorizon Doğru, teşekkürler!
florisla

Teşekkürler @florisia! Uygulama dağıtımı için virtualenvwrapper'dan yerleşik venv'e geçiş sürecindeyim ve açıklamanız bana bunun nasıl yapılacağı konusunda bir şablon verdi. Sadece if hasattr(sys, 'real_prefix'):işe yaramayan teste güveniyordum .
usonianhorizon

8

Sen yapabilir which pythonve onun sanal env'deki birine işaret olmadığını görmek.


1
whichWindows'ta varsayılan olarak kullanılamaz. Bunun whereyerine Windows'ta kullanabilir veya hangi taşıtları kullanabilirsiniz . Veya bakın sys.executable. Ama yine de, daha iyi yöntemler var.
florisla

5
  • Güncelleme Kasım 2019 (ekli).

Ben rutin olarak birkaç Anaconda yüklü sanal ortam (venv) kullanıyorum. Bu kod snippet'i / örnekleri, bir venv'de (veya sistem ortamınızda) olup olmadığınızı belirlemenizi ve ayrıca komut dosyanız için belirli bir venv gerektirmenizi sağlar.

Python komut dosyasına ekle (kod snippet'i):

# ----------------------------------------------------------------------------
# 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! ... ]

Misal:

$ 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) $

Güncelleme 1 - bash komut dosyalarında kullanın:

Bu yaklaşımı bash komut dosyalarında da kullanabilirsiniz (örneğin, belirli bir sanal ortamda çalıştırılması gerekenler). Örnek (bash betiğine eklendi):

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

Güncelleme 2 [Kasım 2019]

Orijinal yazımdan beri Anaconda venv'den taşındım (ve Python'un kendisi viz-a- viz'i geliştirdi sanal ortamlarını geliştirdi).

Bu sorunu yeniden inceleyerek, belirli bir Python sanal ortamında (venv) çalıştığınızı test etmek için ekleyebileceğiniz bazı güncellenmiş Python kodları.

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()

İşte bazı açıklayıcı kod.

[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

En kolay yol sadece koşmaktır: which pythonEğer bir sanal ortamdaysanız, küresel olan yerine pythonunu gösterecektir.


1
Bu aslında ("mevcut komut dosyası" ile ilgili) soruyu cevapladı sanmıyorum. Ancak bu benim özel sorum olan "komut satırından sanal bir ortamda olup olmadığımı nasıl öğrenebilirim?"
ukrutt

1

Bu şekilde buldum, ne düşünüyorsun? (ayrıca venv taban yolunu döndürür ve env değişkeninin kontrol edilmediği okumalar için bile çalışır ):

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

Burada zaten yayınlanan birçok harika yöntem var, ancak sadece bir tane daha ekliyoruz:

import site
site.getsitepackages()

pippaketleri nereye yüklediğinizi söyler .


Bu, Python'un sanal bir ortamda çalışıp çalışmadığını göstermez.
florisla

@florisla Ayrıntı verebilir misiniz? site.getsitepackages()Sistem dizini olmayan bir dizin çıkarırsa , sanal bir ortamda olduğunuzu çıkarabilirsiniz.
flow2k

Python'u birden çok yere kurabilirsiniz. Örneğin, Windows'ta bir 'sistem' Python ve WinPython dağıtımı artı Conda tabanlı bir Python yükleyebilirsiniz. Bunların hepsinde farklı site paketleri klasörleri vardır, ancak a virtualenv.
florisla

@florisla İyi bir nokta - Ben sadece (venv ya da değil) soruyu soruyor olduğunu gördüm (başka bir soru için benzer bir cevap yazmıştı). Bunun bir venv'de olup olmadığınıza dair kesin cevap vermeyebileceğini, ancak hangi Python'u veya hangisini venvkullandığınızı söylemenize yardımcı olabileceğini kabul ediyorum.
flow2k

-1

Kurşun geçirmez değil, UNIX ortamları için basit bir test

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

benim için harika çalışıyor. Daha sonra bazı özniteliklerin varlığını test etmek daha kolaydır ve yine de venv dizininizi adlandırmalısınız venv.


-1

Windows işletim sisteminde böyle bir şey görürsünüz:

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

Parantez, aslında "virtualEnvName" adlı sanal ortamda olduğunuz anlamına gelir.


Sen ve ben 'virtualEnvName' okuyabiliriz. Ancak soru, bir Python modülünün bunu nasıl okuyabileceğidir.
florisla

-1

Bir potansiyel çözüm:

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

Benim durumumda gerçekten pip ile öğeleri olduğu gibi yükleyebilir miyim tespit etmek istedim. Tüm durumlar için doğru çözüm olmayabilir, ancak Python yürütülebilir dosyasının konumu için yazma izinlerine sahip olup olmadığınızı kontrol etmeyi düşünün.

Not: Bu, Python'un tüm sürümlerinde çalışır, ancak Truesistemi Python ile çalıştırırsanız da geri döner sudo. Potansiyel bir kullanım örneği:

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

Bu eski bir sorudur, ancak yukarıdaki çok fazla örnek aşırı karmaşıktır.

Basit Olsun: (Windows 10'da Jupyter Notebook veya Python 3.7.1 terminalinde)


import sys
print(sys.executable)```

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

OR 
```sys.base_prefix```

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

Bu envsyoldaki varlığını kontrol etmek için mantık eklerseniz , anaconda'dan virtualenvveya 'ya geçtiğinizde bu çalışma durur pipenv.
florisla

Florisla, sınırlar içinde benim için çalışan bir cevap verdikten yaklaşık 3 ay sonra "Nasıl yapmamalıyım" cevabını girdiniz (virtualenv ve pipenv arasında hareket etmiyorum). Kendi görünümünüzü daha iyi hale getirmek için diğer insanların cevaplarını küçümsemek kötü bir spor.
Zengin Lysakowski Doktora

Zengin, sizin için işe yarayan başka insanlar için işe yaramayabilir. Orijinal poster için bile işe yaramayabilir.
florisla
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.