Импорт одного и того же модуля более одного раза

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

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)

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

from fileA import *

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

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

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

2 ответа

Решение

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

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

folderA / fileB.py

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

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

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

  • Никогда и никогда не использовал import *, Это загрязняет ваше пространство имен и делает ваш код непредсказуемым.

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

Другие вопросы по тегам