Импорт одного и того же модуля более одного раза
Поэтому через несколько часов я обнаружил причину ошибки в моем приложении. Источник моего приложения структурирован так:
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
или что-нибудь еще; это сделает ваш код намного проще для отслеживания, перемещения и установки.