Apakah mungkin untuk menentukan apakah skrip saat ini berjalan di dalam lingkungan virtualenv?
Apakah mungkin untuk menentukan apakah skrip saat ini berjalan di dalam lingkungan virtualenv?
Jawaban:
AFAIK cara yang paling dapat diandalkan untuk memeriksa ini (dan cara yang digunakan secara internal di virtualenv dan di pip) adalah untuk memeriksa keberadaan sys.real_prefix
:
import sys
if hasattr(sys, 'real_prefix'):
#...
Di dalam virtualenv, sys.prefix
menunjuk ke direktori virtualenv, dan sys.real_prefix
menunjuk ke awalan "nyata" dari sistem Python (sering /usr
atau /usr/local
atau semacamnya).
Di luar virtualenv, sys.real_prefix
seharusnya tidak ada.
Menggunakan VIRTUAL_ENV
variabel lingkungan tidak dapat diandalkan. Ini diatur oleh activate
skrip virtualenv shell, tetapi virtualenv dapat digunakan tanpa aktivasi dengan langsung menjalankan executable dari direktori virtualenv bin/
(atau Scripts
), dalam hal $VIRTUAL_ENV
ini tidak akan ditetapkan.
PYTHON_ENV=$(python -c "import sys; sys.stdout.write('1') if hasattr(sys, 'real_prefix') else sys.stdout.write('0')")
Coba gunakan pip -V
(perhatikan modal V)
Jika Anda menjalankan env virtual. itu akan menunjukkan jalur ke lokasi env.
virtualenv
, ada kemungkinan ini bisa gagal atau berbohong kepada Anda. Jika itu bohong, Anda bisa melakukannya find /path/to/venv/ -type f -exec sed -ie "s:/old/path/to/venv:/path/to/venv:g" {} \+
. Jika gagal (saya mendapat "data marshal buruk") Anda harus menghapus file .pyc dengan find /path/to/venv -type f -name "*.pyc" -exec rm {} \+
(jangan khawatir, mereka akan membangun kembali secara otomatis).
...\lib\site-packages
di %PATH%
. Jadi itu akan mengembalikan false positive dalam kasus itu.
Ini adalah peningkatan dari jawaban yang diterima oleh Carl Meyer . Ia bekerja dengan virtualenv untuk Python 3 dan 2 dan juga untuk modul venv di Python 3:
import sys
def is_venv():
return (hasattr(sys, 'real_prefix') or
(hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix))
Pemeriksaan untuk sys.real_prefix
penutup virtualenv, persamaan non-kosong sys.base_prefix
dengan sys.prefix
penutup venv.
Pertimbangkan skrip yang menggunakan fungsi seperti ini:
if is_venv():
print('inside virtualenv or venv')
else:
print('outside virtualenv or venv')
Dan doa berikut:
$ 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
def is_venv(): return hasattr(sys, 'real_prefix') or sys.base_prefix != sys.prefix
. Katakan saja.
pipenv
lingkungan virtual yang dibuat.
Periksa $VIRTUAL_ENV
variabel lingkungan.
The $VIRTUAL_ENV
variabel lingkungan berisi direktori lingkungan virtual ketika dalam lingkungan virtual yang aktif.
>>> import os
>>> os.environ['VIRTUAL_ENV']
'/some/path/project/venv'
Setelah Anda menjalankan deactivate
/ meninggalkan lingkungan virtual, $VIRTUAL_ENV
variabel akan dihapus / kosong. Python akan menaikkan a KeyError
karena variabel lingkungan tidak disetel.
>>> 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'
Pemeriksaan variabel lingkungan yang sama ini tentu saja dapat juga dilakukan di luar skrip Python, di shell.
virtualenv
virtualenv dan venv
virtualenv.
Menurut virtualenv pep di http://www.python.org/dev/peps/pep-0405/#specification, Anda bisa menggunakan sys.prefix sebagai ganti os.environ ['VIRTUAL_ENV'].
sys.real_prefix tidak ada di virtualenv saya dan sama dengan sys.base_prefix.
sys.real_prefix
.
env |grep VIRTUAL_ENV |wc -l
yang akan mengembalikan 1 jika dalam venv atau 0 jika tidak.
[[ -n $VIRTUAL_ENV ]] && echo virtualenv
atau [[ -z $VIRTUAL_ENV ]] && echo not virtualenv
bergantung pada kebutuhan Anda.
Untuk memeriksa apakah bagian dalam Virtualenv Anda:
import os
if os.getenv('VIRTUAL_ENV'):
print('Using Virtualenv')
else:
print('Not using Virtualenv')
Anda juga dapat memperoleh lebih banyak data tentang lingkungan Anda:
import sys
import os
print(f'Python Executable: {sys.executable}')
print(f'Python Version: {sys.version}')
print(f'Virtualenv: {os.getenv("VIRTUAL_ENV")}')
Ada beberapa jawaban bagus di sini, dan beberapa di antaranya kurang kuat. Inilah ikhtisar.
Jangan bergantung pada lokasi Python atau site-packages
folder.
Jika ini disetel ke lokasi non-standar, itu tidak berarti Anda sebenarnya berada di lingkungan virtual. Pengguna dapat menginstal lebih dari satu versi Python, dan itu tidak selalu sesuai dengan yang Anda harapkan.
Hindari melihat:
sys.executable
sys.prefix
pip -V
which python
Juga, jangan periksa keberadaan venv
, .venv
atau envs
di jalur mana pun. Ini akan merusak lingkungan dengan lokasi yang lebih unik. Misalnya,
Pipenv menggunakan nilai hash sebagai nama untuk lingkungannya.
VIRTUAL_ENV
variabel lingkunganKeduanya virtualenv
dan venv
mengatur variabel lingkungan $VIRTUAL_ENV
saat mengaktifkan suatu lingkungan. Lihat PEP 405 .
Anda dapat membaca variabel ini dalam skrip shell, atau menggunakan kode Python ini untuk menentukan apakah sudah disetel.
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"))
Masalahnya adalah, ini hanya berfungsi ketika lingkungan diaktifkan oleh activate
skrip shell.
Anda dapat memulai skrip lingkungan tanpa mengaktifkan lingkungan , jadi jika itu merupakan masalah, Anda harus menggunakan metode yang berbeda.
sys.base_prefix
virtualenv
, venv
dan pyvenv
arahkan sys.prefix
ke Python yang terinstal di dalam virtualenv seperti yang Anda harapkan.
Pada saat bersamaan, asli nilai sys.prefix
juga dibuat tersedia sebagai sys.base_prefix
.
Kita bisa menggunakannya untuk mendeteksi jika kita berada di 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
Sekarang hati-hati, virtualenv
sebelum versi 20 tidak diatursys.base_prefix
tetapi diatursys.real_prefix
sebagai gantinya.
Agar aman, periksa keduanya seperti yang disarankan dalam jawaban 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
Jika Anda menggunakan lingkungan virtual Anaconda, periksa jawaban Victoria Stuart .
running_in_virtualenv = sys.*base_*prefix != sys.prefix
if hasattr(sys, 'real_prefix'):
tes, yang tidak lagi berhasil.
Anda dapat melakukan which python
dan melihat apakah ini menunjuk ke yang ada di virtual env.
which
tidak tersedia secara default di Windows. Anda bisa menggunakan where
hanya pada Windows, atau mempekerjakan whichcraft . Atau lihat sys.executable
. Tapi tetap saja, ada metode yang lebih baik.
Saya secara rutin menggunakan beberapa lingkungan virtual yang diinstal Anaconda (venv). Cuplikan kode / contoh ini memungkinkan Anda untuk menentukan apakah Anda berada di venv (atau lingkungan sistem Anda), dan juga membutuhkan venv spesifik untuk skrip Anda.
Tambahkan ke skrip Python (cuplikan kode):
# ----------------------------------------------------------------------------
# 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! ... ]
Contoh:
$ 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) $
Perbarui 1 - gunakan dalam skrip bash:
Anda juga dapat menggunakan pendekatan ini dalam skrip bash (mis., Yang harus dijalankan dalam lingkungan virtual tertentu). Contoh (ditambahkan ke skrip 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
Pembaruan 2 [Nov 2019]
Sejak posting asli saya, saya sudah pindah dari Anaconda venv (dan Python itu sendiri telah berevolusi viz-a-viz lingkungan virtual).
Memeriksa ulang masalah ini, berikut adalah beberapa kode Python yang diperbarui yang dapat Anda masukkan untuk menguji apakah Anda beroperasi di lingkungan virtual (vv) Python tertentu.
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()
Berikut ini beberapa kode penjelasan.
[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! :-)
>>>
Cara termudah adalah dengan hanya menjalankan which python
:, jika Anda berada dalam virtualenv itu akan menunjuk ke python bukan global
(diedit) Saya menemukan cara itu, bagaimana menurut Anda? (itu juga mengembalikan jalur dasar venv dan bekerja bahkan untuk readthedocs di mana memeriksa variabel env tidak):
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'] + '/../')
Ada banyak metode hebat yang sudah diposting di sini, tetapi hanya menambahkan satu lagi:
import site
site.getsitepackages()
memberitahu Anda di mana pip
menginstal paket.
site.getsitepackages()
menampilkan direktori yang bukan sistem, maka Anda dapat menyimpulkan bahwa Anda berada di lingkungan virtual.
virtualenv
.
venv
Anda gunakan.
Ini bukan anti peluru tetapi untuk lingkungan UNIX seperti tes sederhana
if run("which python3").find("venv") == -1:
# something when not executed from venv
bekerja bagus untukku. Lebih sederhana daripada menguji ada beberapa atribut dan, bagaimanapun, Anda harus memberi nama direktori venv Anda venv
.
Di OS windows Anda melihat sesuatu seperti ini:
C:\Users\yourusername\virtualEnvName\Scripts>activate
(virtualEnvName) C:\Users\yourusername\virtualEnvName\Scripts>
Tanda kurung berarti bahwa Anda sebenarnya berada di lingkungan virtual yang disebut "virtualEnvName".
Sebuah potensi solusi adalah:
os.access(sys.executable, os.W_OK)
Dalam kasus saya, saya benar-benar hanya ingin mendeteksi apakah saya dapat menginstal item dengan pip apa adanya. Meskipun ini mungkin bukan solusi yang tepat untuk semua kasus, pertimbangkan untuk memeriksa apakah Anda memiliki izin menulis untuk lokasi eksekusi Python.
Catatan: ini berfungsi di semua versi Python, tetapi juga kembali True
jika Anda menjalankan sistem Python sudo
. Berikut ini adalah kasus penggunaan potensial:
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'])
Ini adalah pertanyaan lama, tetapi terlalu banyak contoh di atas terlalu rumit.
Keep It Simple: (dalam terminal Jupyter Notebook atau Python 3.7.1 pada Windows 10)
import sys
print(sys.executable)```
# example output: >> `C:\Anaconda3\envs\quantecon\python.exe`
OR
```sys.base_prefix```
# Example output: >> 'C:\\Anaconda3\\envs\\quantecon'
envs
di jalur itu, ini akan berhenti berfungsi ketika Anda berpindah dari anaconda ke virtualenv
atau pipenv
.