2015-07-08 1 views
11

У меня недавно возникла проблема с python ImportError, где модуль был найден при работе на моем локальном компьютере, но не найденных на сервере CI. Я решил эту проблему, заменив sys.path.append(path) в моем скрипте с sys.path.insert(0, path), где path - это расположение строкового модуля.Влияние использования sys.path.insert (0, path) и sys.path (append) при загрузке модулей

Поскольку это мой модуль, а не установленный пакет (related question), почему порядок путей устраняет эту проблему?

+0

Возможный дубликат [Зачем использовать sys.path.append (путь) вместо sys.path.insert (1, путь)?] (Http://stackoverflow.com/questions/10095037/why-use-sys- путь-appendpath-вместо-sys-path-insert1-path) – CrandellWS

ответ

9

Поскольку python проверяет в каталогах в порядке очередности, начиная с первого каталога в sys.path, пока не найдет файл .py, который он искал.

В идеале, текущий каталог или каталог сценария является первым всегда первым элементом в списке, если вы не измените его, как вы это делали. Из documentation -

As initialized upon program startup, the first item of this list, path[0], is the directory containing the script that was used to invoke the Python interpreter. If the script directory is not available (e.g. if the interpreter is invoked interactively or if the script is read from standard input), path[0] is the empty string, which directs Python to search modules in the current directory first. Notice that the script directory is inserted before the entries inserted as a result of PYTHONPATH.

Так что, скорее всего, вы имели .py файл с таким же именем, что и модуль вы пытаетесь импортировать из, в текущем каталоге (где скрипт запускается с).

Кроме того, вещь отметить о ImportError с, позволяет сказать, что ошибка импорта говорит - ImportError: No module named main - это не значит, что main.py переписывается, нет, если это был переписан мы бы не возникли проблемы, пытаясь прочитать его. Его некоторый модуль выше этого, который был перезаписан a. py или какой-либо другой файл.

Пример -

Моя структура каталогов выглядит -

- test 
    - shared 
     - __init__.py 
     - phtest.py 
    - testmain.py 

Теперь из testmain.py, я называю from shared import phtest, он отлично работает.

Теперь позволяет сказать, что я ввести shared.py в test directory`, пример -

- test 
    - shared 
     - __init__.py 
     - phtest.py 
    - testmain.py 
    - shared.py 

Теперь, когда я пытаюсь сделать from shared import phtest из testmain.py, я получаю ошибку -

ImportError: cannot import name 'phtest' 

Как вы можете видеть выше, файл, вызывающий проблему, составляет shared.py, а не phtest.py.

+0

Мой модуль был something.main, я попытался изменить его на что-то. Задайте, чтобы увидеть, если это была проблема, однако у меня все еще был ImportError, это заставляет меня думаю, что это было не имя файла/файла. –

+0

Какова была ошибка импорта? –

+1

Последней строкой трассировки был «ImportError: No module named main» –

6

Я совсем новичок в Python и я нашел ответ Ананда был очень хорош, но довольно сложным для меня, поэтому я стараюсь переформулировать:

1) insert и append методы не являются специфическими для sys.path и как и в других языках, они добавляют элемент в виде списка или массива, а также:
* append(item) добавить item в конец списка,
* insert(n, item) вставляет item на п-й позиции в списке (0 в начале, 1 после первый элемент и т. д. ...).

2) Как сказал Ананд, питон искать файлы импорта в каждом каталоге пути в порядке пути, так:
* Если у вас нет конфликтов имен файлов, порядок пути не имеет никакого влияния,
* Если вы ищете функцию, уже определенную в пути, и вы используете append, чтобы добавить свой путь, вы не получите свою функцию, а предопределенную.

Но я думаю, что лучше использовать append, а не insert, чтобы не перегружать стандартное поведение Python и использовать недвусмысленные имена для ваших файлов и методов.

Смежные вопросы