Mengapa menggunakan sys.path.append (path) daripada sys.path.insert (1, path)?

89

Sunting: berdasarkan komentar Ulf Rompe, penting untuk Anda menggunakan "1" daripada "0" , jika tidak, Anda akan merusak sys.path .

Saya telah melakukan python untuk beberapa waktu sekarang (lebih dari satu tahun), dan saya selalu bingung mengapa orang merekomendasikan Anda menggunakan sys.path.append()bukan sys.path.insert(). Biar saya tunjukkan.

Katakanlah saya sedang mengerjakan modul bernama PyWorkbooks (yang diinstal di komputer saya), tetapi saya secara bersamaan mengerjakan modul yang berbeda (katakanlah PyJob) yang menggabungkan PyWorkbooks. Saat saya mengerjakan PyJob, saya menemukan kesalahan di PyWorkbooks yang sedang saya koreksi, jadi saya ingin mengimpor versi pengembangan.

Ada beberapa cara untuk mengerjakan keduanya (saya bisa meletakkan proyek PyWorkbooks saya di dalam PyJob, misalnya), tetapi terkadang saya masih perlu bermain-main dengan jalurnya. Namun, saya tidak bisa begitu saja melakukan sys.path.append()ke folder tempat PyWorkbooks berada . Mengapa? Karena python akan menemukan PyWorkbooks saya yang terinstal terlebih dahulu!

Inilah mengapa Anda harus melakukan sys.path.insert (1, path_to_dev_pyworkbooks)

Singkatnya:

sys.path.append(path_to_dev_pyworkbooks)
import PyWorkbooks # does NOT import dev pyworkbooks, imports installed one

atau:

sys.path.insert(1, path_to_dev_pyworkbooks) # based on comments you should use **1 not 0**
import PyWorkbooks # imports correct file

Hal ini telah menyebabkan beberapa hangup bagi saya di masa lalu, dan saya akan sangat menyukainya jika kami (sebagai komunitas) mulai merekomendasikan sys.path.insert(1, path), seolah-olah Anda memasukkan jalur secara manual, menurut saya aman untuk mengatakan bahwa itu adalah jalur yang Anda inginkan menggunakan!

Atau apakah saya memiliki sesuatu yang salah? Ini adalah pertanyaan yang terkadang mengganggu saya dan saya menginginkannya di tempat terbuka!

Garrett Berg
sumber
3
Saya sudah selesai sys.path.insert(1, dev_folder)tetapi masih belum menemukan modul dev, dan hanya menggunakan modul yang diinstal. Bagaimana cara mengatasinya?
endolith

Jawaban:

47

Jika Anda memiliki beberapa versi paket / modul, Anda harus menggunakan virtualenv (penekanan saya):

virtualenv adalah alat untuk membuat lingkungan Python yang terisolasi.

Masalah dasar yang sedang ditangani adalah salah satu dependensi dan versi, dan izin secara tidak langsung. Bayangkan Anda memiliki aplikasi yang membutuhkan LibFoo versi 1, tetapi aplikasi lain memerlukan versi 2. Bagaimana Anda dapat menggunakan kedua aplikasi ini? Jika Anda menginstal semuanya ke dalam /usr/lib/python2.7/site-packages(atau apa pun lokasi standar platform Anda), mudah untuk berakhir dalam situasi di mana Anda secara tidak sengaja memutakhirkan aplikasi yang seharusnya tidak ditingkatkan.

Atau secara lebih umum, bagaimana jika Anda ingin menginstal aplikasi dan membiarkannya ? Jika aplikasi berfungsi, perubahan apa pun di pustaka atau versi pustaka tersebut bisa merusak aplikasi.

Juga, bagaimana jika Anda tidak dapat menginstal paket ke site-packagesdirektori global ? Misalnya, pada host bersama.

Dalam semua kasus ini, virtualenvdapat membantu Anda. Ini menciptakan lingkungan yang memiliki direktori instalasinya sendiri, yang tidak berbagi perpustakaan dengan lingkungan virtualenv lain (dan secara opsional juga tidak mengakses perpustakaan yang diinstal secara global).

Itulah mengapa orang menganggapnya insert(0, salah - ini adalah solusi sementara yang tidak lengkap untuk masalah mengelola banyak lingkungan.

agf
sumber
Terima kasih, saya samar-samar tahu sesuatu seperti ini ada tetapi saya belum benar-benar memeriksanya sampai sekarang. Jadi yang harus saya lakukan dengan ini adalah menjalankan segala sesuatu mulai dari penerjemah di lingkungan virtual ... yang bisa berfungsi dengan baik. Terima kasih!
Garrett Berg
1
Ini adalah saran tetapi tidak langsung menjawab pertanyaan (misalnya saya memiliki alasan kuat untuk tidak menggunakan virtualenvdan sebenarnya sedang mencari jawaban yang terkait dengan OP)
StephenBoesch
@javadba Itu mungkin benar untuk kasus Anda, tetapi kebanyakan orang yang menanyakan pertanyaan ini seharusnya menggunakan venv.
agf
46

Jika Anda benar-benar perlu menggunakan sys.path.insert, pertimbangkan untuk membiarkan sys.path [0] apa adanya:

sys.path.insert(1, path_to_dev_pyworkbooks)

Ini mungkin penting karena kode pihak ketiga mungkin bergantung pada kesesuaian dokumentasi sys.path :

Seperti yang diinisialisasi saat program dimulai, item pertama dari daftar ini, path [0], adalah direktori yang berisi skrip yang digunakan untuk memanggil interpreter Python.

Ulf Rompe
sumber
13

Anda membingungkan konsep appending dan prepending. kode berikut adalah prepending:

sys.path.insert(1,'/thePathToYourFolder/')

itu menempatkan informasi baru di awal (yah, kedua, tepatnya) dari urutan pencarian yang akan dilalui oleh penerjemah Anda. sys.path.append()meletakkan hal-hal di akhir urutan pencarian.

Sangat disarankan agar Anda menggunakan sesuatu seperti virtualenvdaripada mengkodekan direktori paket Anda secara manual ke PYTHONPATHsetiap saat. untuk menyiapkan berbagai ekosistem yang memisahkan paket situs Anda dan kemungkinan versi python, baca dua blog ini:

  1. pengenalan ekosistem python

  2. bootstrap lingkungan virtual python

jika Anda memutuskan untuk beralih ke jalur isolasi lingkungan, Anda pasti akan mendapat manfaat dengan melihat ke virtualenvwrapper: http://www.doughellmann.com/docs/virtualenvwrapper/

samkhan13
sumber
1
Tautan "pengenalan ekosistem python", "lingkungan virtual bootstrap python" telah dihentikan, mohon pertimbangkan untuk merevitalisasi mereka.
Pradeep Singh