Python - ошибка импорта - PullRequest
       20

Python - ошибка импорта

2 голосов
/ 15 апреля 2010

Я сделал то, чего не должен был делать, и написал 4 модуля (около 6 часов), не выполняя никаких тестов.

У меня есть метод внутри /mydir/__init__.py с именем get_hash() и класс внутри /mydir/utils.py с именем SpamClass.

/mydir/utils.py импортирует get_hash() из /mydir/__init__.

/mydir/__init__.py импорт SpamClass из /mydir/utils.py.

И класс, и метод работают отлично, но по какой-то причине, если я пытаюсь импортировать /mydir/, я получаю ошибку импорта, говорящую "Cannot import name get_hash" из /mydir/__init__.py.

Единственная трассировка стека - это строка о том, что __init__.py импортировано SpamClass. Следующая строка содержит ошибку в SpamClass при попытке импортировать get_hash. Почему это?

Ответы [ 3 ]

2 голосов
/ 15 апреля 2010

Это довольно простая проблема. Происходит следующее: переводчик оценивает ваш __init__.py файл построчно. Когда у вас есть следующий код:

 import mydir.utils
 def get_hash(): return 1

Интерпретатор приостанавливает обработку __init__.py в точке import mydir.utils до тех пор, пока он не выполнит полностью mydir / utils.py. Поэтому, когда utils.py пытается импортировать get_hash (), он не определяется, поскольку интерпретатор еще не дошел до определения.

2 голосов
/ 15 апреля 2010

Чтобы добавить к тому, что сказали другие, еще один хороший способ избежать проблем кругового импорта - это избегать from module import stuff.

Если вы просто сделаете стандартный import module в верхней части каждого скрипта и напишите module.stuff в своих функциях, то к тому времени, когда эти функции запустятся, импорт будет завершен, и все члены модуля будут доступны.

Тогда вам также не придется беспокоиться о ситуациях, когда некоторые модули могут обновлять / изменять одного из своих участников (или его непонятно исправляет непослушная третья сторона). Если вы импортировали from модуль, у вас все еще была бы старая, устаревшая копия участника.

Лично я использую from - import только для простых, не зависимых от членов, к которым я, скорее всего, буду ссылаться: в частности, на символические константы.

1 голос
/ 15 апреля 2010

В отсутствие дополнительной информации я бы сказал, что у вас есть циклический импорт, который вы не работаете. Самое простое и очевидное решение - не помещать в mydir/__init__.py то, что вы хотите использовать, из любого модуля внутри mydir. Итак, переместите вашу функцию get_hash в другой модуль внутри пакета mydir и импортируйте этот модуль туда, где он вам нужен.

...