Di mana di virtualenv kode kustom pergi?

107

Struktur direktori macam apa yang harus diikuti saat menggunakan virtualenv? Misalnya, jika saya sedang membangun aplikasi WSGI dan membuat virtualenv bernama foobarsaya akan mulai dengan struktur direktori seperti:

/foobar
  /bin
    {activate, activate.py, easy_install, python}
  /include
    {python2.6/...}
  /lib
    {python2.6/...}

Setelah lingkungan ini dibuat, di mana satu tempat akan menjadi miliknya:

  • file python?
  • file statis (gambar / dll)?
  • paket "khusus", seperti yang tersedia secara online tetapi tidak ditemukan di toko keju?

dalam kaitannya dengan virtualenvdirektori?

(Asumsikan saya sudah tahu ke mana direktori virtualenv itu sendiri harus pergi .)

Phillip B Oldham
sumber
8
@jkp: Saya tidak setuju. Bagaimana Anda mengatur tata letak aplikasi python adalah masalah yang berbeda dari bagaimana Anda menemukan aplikasi itu dalam virtualenv untuk tujuan pengembangan. Itu terkait, tapi tidak sama. Harap jangan tutup sebagai duplikat.
jcdyer

Jawaban:

90

virtualenvmenyediakan instance interpreter python, bukan instance aplikasi. Anda biasanya tidak akan membuat file aplikasi Anda dalam direktori yang berisi Python default sistem, juga tidak ada persyaratan untuk menemukan aplikasi Anda dalam direktori virtualenv.

Misalnya, Anda mungkin memiliki proyek di mana Anda memiliki beberapa aplikasi menggunakan virtualenv yang sama. Atau, Anda mungkin menguji aplikasi dengan virtualenv yang nantinya akan digunakan dengan sistem Python. Atau, Anda mungkin mengemas aplikasi mandiri di mana mungkin masuk akal untuk memiliki direktori virtualenv yang terletak di suatu tempat di dalam direktori aplikasi itu sendiri.

Jadi, secara umum, saya rasa tidak ada satu jawaban yang benar untuk pertanyaan itu. Dan, hal baiknya virtualenvadalah ia mendukung banyak kasus penggunaan yang berbeda: tidak perlu ada satu cara yang benar.

Ned Deily
sumber
8
Sepakat. Saya menggunakan virtualenv untuk semua yang saya lakukan, dan saya tidak pernah menempatkan file di dalam direktori virtualenv. Virtualenv tidak perlu berdampak pada struktur proyek Anda; cukup aktifkan virtualenv (atau gunakan bin / python), dan kerjakan file Anda di mana pun Anda memilikinya.
Carl Meyer
Saya juga setuju dengan sepenuh hati. Satu-satunya waktu saya pernah menyentuh file apapun di dalam virtualenv saya (saya gunakan virtualenvwrapper) adalah ketika saya ingin edit postactivatedan postdeactivatekait.
Thane Brimhall
Pertanyaan akan lebih baik disajikan dengan contoh konkret dan praktis dari berbagai opsi termasuk pertukaran seperti yang terlihat pada jawaban lain dalam pertanyaan ini.
andyfeller
2
Lebih bersih untuk menjaga proyek Anda terpisah ke virtualenvdirektori, tetapi membandingkan virtualenvdengan sistem python tidak membantu, karena tujuannya virtualenvadalah untuk memperbaiki dependensi yang rusak dan mengisolasi proyek sehingga mereka dapat menggunakan versi paket yang berbeda dan bahkan versi python (saya menyadari ini ditulis sebelumnya -python3). Mengizinkan aplikasi untuk berbagi virtualenvmenggunakan virtualenvseolah-olah itu adalah python sistem, membuat aplikasi rentan terhadap masalah yang sama yang dirancang untuk diselesaikan oleh virtualenv. There should be one obvious way to do it; logisnya seharusnya 1: 1
Davos
@Ned: Mencoba memperoleh beberapa praktik terbaik, tetapi masih belum jelas: jika Anda memiliki lusinan proyek, masing-masing dengan virtualenvnya sendiri, lalu bagaimana Anda melacak proyek mana yang digunakan dengan virtualenv mana? Tambahkan skrip shell kecil di root setiap folder dengan nama virtualenv yang Anda gunakan?
ccpizza
57

Jika Anda hanya memiliki beberapa proyek sesekali, tidak ada yang menghentikan Anda untuk membuat virtualenv baru untuk masing-masing proyek, dan meletakkan paket Anda tepat di dalam:

/foobar
  /bin
    {activate, activate.py, easy_install, python}
  /include
    {python2.6/...}
  /lib
    {python2.6/...}
  /mypackage1
    __init__.py
  /mypackage2
    __init__.py

Keuntungan dari pendekatan ini adalah Anda selalu bisa yakin untuk menemukan skrip pengaktifan yang dimiliki proyek di dalamnya.

$ cd /foobar
$ source bin/activate
$ python 
>>> import mypackage1
>>>

Jika Anda memutuskan untuk sedikit lebih terorganisir, Anda harus mempertimbangkan untuk meletakkan semua virtualenv Anda ke dalam satu folder, dan beri nama masing-masing setelah proyek yang Anda kerjakan.

  /virtualenvs
    /foobar
      /bin
        {activate, activate.py, easy_install, python}
      /include
        {python2.6/...}
      /lib
        {python2.6/...}
  /foobar
    /mypackage1
      __init__.py
    /mypackage2
      __init__.py

Dengan cara ini Anda selalu dapat memulai kembali dengan virtualenv baru jika terjadi kesalahan, dan file proyek Anda tetap aman.

Keuntungan lainnya adalah beberapa project Anda dapat menggunakan virtualenv yang sama, jadi Anda tidak perlu melakukan penginstalan yang sama berulang kali jika Anda memiliki banyak dependensi.

$ cd /foobar
$ source ../virtualenvs/foobar/bin/activate
$ python 
>>> import mypackage2
>>>

Untuk pengguna yang secara teratur harus menyiapkan dan menghancurkan virtualenv, masuk akal untuk melihat virtualenvwrapper.

http://pypi.python.org/pypi/virtualenvwrapper

Dengan virtualenvwrapper Anda bisa

* create and delete virtual environments

* organize virtual environments in a central place

* easily switch between environments

Anda tidak perlu lagi khawatir tentang di mana virtualenv Anda saat mengerjakan proyek "foo" dan "bar":

  /foo
    /mypackage1
      __init__.py
  /bar
    /mypackage2
      __init__.py

Beginilah cara Anda mulai mengerjakan proyek "foo":

$ cd foo
$ workon
bar
foo
$ workon foo
(foo)$ python
>>> import mypackage1
>>>

Kemudian beralih ke proyek "bar" sesederhana ini:

$ cd ../bar
$ workon bar
(bar)$ python
>>> import mypackage2
>>>

Cukup rapi, bukan?

Maik Röder
sumber
Saya sangat setuju dengan jawaban tentang penggunaan ini virtualenvwrapper. Ini dengan rapi mengabstraksi virtualenv sambil tetap memberi Anda semua manfaat.
Thane Brimhall
5
Tetapi sangat tidak setuju tentang PERNAH menempatkan kode Anda di dalam lingkungan virtual. Jika Anda ingin "dekat" proyek pada sistem file, letakkan venv/direktori pada tingkat yang sama dengan proyek BASE_DIR.
Rob Grant
30

Karena virtualenv tidak dapat direlokasi, menurut saya itu adalah praktik yang buruk untuk menempatkan file proyek Anda di dalam direktori virtualenv. Virtualenv itu sendiri adalah artefak pengembangan / penerapan yang dihasilkan (semacam file .pyc), bukan bagian dari proyek; seharusnya mudah untuk menghapusnya dan membuatnya kembali kapan saja, atau membuat yang baru di host penerapan baru, dll.

Banyak orang pada kenyataannya menggunakan virtualenvwrapper , yang menghapus virtualenvs sebenarnya dari kesadaran Anda hampir sepenuhnya, menempatkan semuanya berdampingan di $ HOME / .virtualenvs secara default.

Carl Meyer
sumber
Sepenuhnya setuju bahwa ini adalah praktik yang buruk, bagus untuk menunjukkan bahwa itu harus mudah diledakkan dan dibuat ulang, terutama untuk menguji penerapan dan mengurangi paket persyaratan yang tidak diperlukan. Hanya ingin menambahkan bahwa virtualenv dapat direlokasi menggunakan misalnya virtualenv --relocatable myvenvlihat stackoverflow.com/a/6628642/1335793 hanya karena Anda tidak bisa berarti Anda harus melakukannya.
Davos
2

Jika Anda memberikan proyek Anda setup.py, pip dapat mengimpornya dari kontrol versi secara langsung.

Lakukan sesuatu seperti ini:

$ virtualenv --no-site-packages myproject
$ . myproject/bin/activate
$ easy_install pip
$ pip install -e hg+http://bitbucket.org/owner/myproject#egg=proj

Ini -eakan memasukkan proyek myproject/src, tetapi menautkannya ke myproject/lib/pythonX.X/site-packages/, sehingga setiap perubahan yang Anda buat akan segera diambil dalam modul yang mengimpornya dari lokal Anda site-packages. The #eggbit memberitahu pip nama apa yang ingin Anda berikan kepada paket telur itu menciptakan untuk Anda.

Jika Anda tidak menggunakan --no-site-packages, berhati-hatilah untuk menentukan bahwa Anda ingin pip diinstal ke virtualenv dengan -Eopsi

jcdyer
sumber