Навіщо використовувати sys.path.append (path) замість sys.path.insert (1, path)?


88

Редагувати: на основі коментаря Ульфа Ромпе важливо використовувати "1" замість "0" , інакше ви порушите sys.path .

Я займаюся python вже досить давно (більше року), і мене завжди бентежить, чому люди рекомендують використовувати sys.path.append()замість цього sys.path.insert(). Дозвольте мені продемонструвати.

Скажімо, я працюю над модулем під назвою PyWorkbooks (який встановлений на моєму комп’ютері), але я одночасно працюю над іншим модулем (скажімо, PyJob), який включає PyWorkbooks. Оскільки я працюю над PyJob, я виявляю помилки в PyWorkbooks, які виправляю, тому я хотів би імпортувати версію для розробки.

Існує декілька способів працювати з обома (наприклад, я міг би помістити свій проект PyWorkbooks всередину PyJob), але іноді мені все одно доведеться пограти із цим шляхом. Однак я не можу просто зробити sys.path.append()папку, в якій знаходиться PyWorkbooks . Чому? Тому що python знайде мої встановлені PyWorkbooks першими!

Ось чому вам потрібно зробити sys.path.insert (1, path_to_dev_pyworkbooks)

Підсумовуючи:

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

або:

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

Це спричинило кілька зависань у мене в минулому, і я б дуже хотів, якби ми (як спільнота) почали рекомендувати sys.path.insert(1, path), ніби ви вручну вставляєте шлях, я думаю, можна з упевненістю сказати, що це той шлях, який ви хочете використовувати!

Або у мене щось не так? Це питання мене іноді турбує, і я хотів, щоб це було відкрито!


3
Я зробив, sys.path.insert(1, dev_folder)але він все ще не знаходить модуль dev, а лише використовує встановлений модуль. Як це виправити?
ендоліт

Відповіді:


47

Якщо у вас кілька версій пакета / модуля, вам потрібно використовувати virtualenv (наголос мій):

virtualenv - це інструмент для створення ізольованих середовищ Python.

Основною проблемою, що вирішується, є одна із залежностей та версій, а також побічно дозволів. Уявіть, у вас є програма, яка потребує версії 1 LibFoo, але інша програма вимагає версії 2. Як ви можете використовувати обидві ці програми? Якщо ви встановите все /usr/lib/python2.7/site-packages(або будь-яке стандартне місце розташування вашої платформи), легко потрапити в ситуацію, коли ви ненавмисно оновите програму, яку не слід модернізувати.

Або більш загально, що, якщо ви хочете встановити програму і залишити її такою ? Якщо програма працює, будь-яка зміна її бібліотек або версій цих бібліотек може зламати програму.

Крім того, що робити, якщо ви не можете встановити пакунки в глобальний site-packagesкаталог? Наприклад, на спільному хості.

У всіх цих випадках virtualenvможе вам допомогти. Він створює середовище, яке має власні каталоги встановлення, яке не ділиться бібліотеками з іншими середовищами virtualenv (і, за бажанням, також не отримує доступ до глобально встановлених бібліотек).

Ось чому люди вважають insert(0, помилковим - це неповне вирішальне рішення проблеми управління кількома середовищами.


Дякую, я неясно знав, що щось подібне існує, але насправді я цього не перевіряв дотепер. Отже, що я мав би з цим робити, це запускати все від інтерпретатора у віртуальному середовищі ..., що також могло б працювати. Дякую!
Гаррет Берг,

1
Це пропозиція, але не відповідає безпосередньо на запитання (наприклад, у мене є вагомі причини не використовувати virtualenvі фактично шукаю відповідну відповідь на ОП)
Джавадба,

@javadba Це може бути правдою для вашого випадку, але більшість людей, які задають це питання, повинні використовувати venv.
agf

46

Якщо вам дійсно потрібно використовувати sys.path.insert, спробуйте залишити sys.path [0] таким, яким він є:

sys.path.insert(1, path_to_dev_pyworkbooks)

Це може бути важливо, оскільки сторонній код може покладатися на відповідність документації sys.path :

Як ініціалізований під час запуску програми, першим елементом цього списку, шляхом [0], є каталог, що містить сценарій, який був використаний для виклику інтерпретатора Python.


13

ви плутаєте поняття додавання та додавання. наступний код додається:

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

вона розміщує нову інформацію на початку (ну, по-друге, якщо бути точним) послідовності пошуку, яку пройде ваш перекладач. sys.path.append()ставить речі в самий кінець послідовності пошуку.

доцільно використовувати щось на кшталт virtualenvзамість того, щоб PYTHONPATHкожен раз кодувати каталоги пакунків . для налаштування різних екосистем, що розділяють ваші веб-сайти та можливі версії python, прочитайте ці два блоги:

  1. введення екосистем пітона

  2. завантаження віртуальних середовищ python

якщо ви все-таки вирішите рухатись по шляху до ізоляції навколишнього середовища, ви, безсумнівно, отримаєте користь, заглянувши у virtualenvwrapper: http://www.doughellmann.com/docs/virtualenvwrapper/


1
Посилання "введення екосистем python", "завантаження віртуальних середовищ python" скасовано, будь ласка, розгляньте можливість їх активізації.
Прадіп Сінгх
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.