импорт одного и того же модуля более одного раза - PullRequest
4 голосов
/ 22 марта 2010

Итак, через несколько часов я обнаружил причину ошибки в моем приложении. Источник моего приложения структурирован как:

main/
    __init__.py
    folderA/
        __init__.py
        fileA.py
        fileB.py

Действительно, есть еще около 50 файлов. Но дело не в этом. В main/__init__.py у меня есть этот код: from folderA.fileA import *

в folderA/__init__.py У меня есть этот код:

sys.path.append(pathToFolderA)

in folderA/fileB.py У меня есть этот код:

from fileA import *

Проблема в том, что файл A импортируется дважды. Однако я хочу импортировать его только один раз.

Очевидный способ исправить это (по крайней мере для меня) - это изменить некоторые пути с path на folderA.path

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

Ответы [ 2 ]

5 голосов
/ 22 марта 2010
  • Изменение sys.path - это не то, что вы делаете в реальной программе.Это наносит вред модульности и мобильности без какой-либо выгоды от постоянной установки PYTHONPATH или размещения вашего модуля в месте, где Python может его найти.Он загрязняет ваше пространство имен и делает ваш код непредсказуемым.

  • Вам не нужна папка A на sys.path.Это подпакет main и всегда должен рассматриваться как таковой.Всегда используйте абсолютный импорт для пакетов верхнего уровня: import main.folderA, а не import folderA или что-либо еще;это сделает ваш код намного проще для отслеживания, перемещения и установки.

5 голосов
/ 22 марта 2010

Не изменяйте sys.path таким способом, поскольку он предоставляет два способа (имена) для доступа к вашим модулям, что приводит к вашей проблеме.

Вместо этого используйте абсолютный или однозначно-относительный импорт . (Неоднозначный импорт может использоваться в качестве крайней меры в старых версиях Python.)

folderA / fileB.py

from main.folderA.fileA import *   # absolute
from .fileA import *               # unambiguous-relative
from fileA import *                # ambiguous-relative

Конечно, вы должны использовать конкретные имена вместо этой звезды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...