хаос импорта вложенной папки python
-
21-12-2019 - |
Вопрос
предположим, у меня есть структура папок, которая выглядит следующим образом:
.
├── A
│ ├── a.py
│ └── b.py
└── main.py
Файлы имеют следующее содержимое:
b.py:
class BClass:
pass
a.py:
from b import BClass
main.py:
from A import a
Если я убегу python3.3 A/a.py
или python3.3 B/b.by
, ошибок нет.Однако, если я запущу python3.3 main.py
, возникает следующая ошибка:
Traceback (most recent call last):
File "main.py", line 1, in <module>
from A import a
File "/tmp/python_imports/A/a.py", line 1, in <module>
from b import BClass
ImportError: No module named 'b'
Изменение строки импорта в a.py на import A.b
работает, но очевидно python3.3 A/a.py
тогда это потерпит неудачу.На самом деле я не заинтересован в беге python3.3 A/a.py
но я хочу, чтобы модуль можно было импортировать из нескольких мест.Следовательно, a.py следует импортировать b.py независимо от того, куда импортируется a.py.
Как можно решить эту проблему?
Решение
Кроме того, __init__.py
Я упоминал в своем комментарии, который является обязательным для пакетов, что вам нужно импортировать родственный модуль относительно:
from .b import BClass
Тогда это также работает в Python 3.
В качестве альтернативы вы, конечно, можете импортировать полное имя:
from A.b import BClass
Но тогда ваш модуль не так легко перемещается внутри вашего дерева пакетов.
Однако ни в том, ни в другом случае вы не сможете использовать a.py
как самостоятельный продукт.Чтобы достичь этого, вам нужно было бы окружить import
заявление с try
/except
и попробуйте другую версию на случай, если первая не сработает:
try:
from .b import BClass
except ValueError:
from b import BClass
Но это и понятно.В более крупной системе модули могут зависеть от других модулей где-то в пакете, в противном случае они, возможно, должны быть не частью пакета, а автономными.И если существуют такие зависимости, использование модуля так, как если бы он был автономным, конечно, будет проблемой.
Другие советы
Вам нужен __init__.py
файл (пустой будет просто отлично) в A
каталог.В противном случае python не распознает его как пакет.
Теперь, когда вы являетесь пакетом, вы должны использовать либо абсолютный импорт, либо явный относительный импорт.В этом случае, в A/a.py
либо используйте from A.b import BClass
или from .b import BClass
.