Импортировать пакет-модуль изнутри и снаружи пакета - PullRequest
0 голосов
/ 12 апреля 2020

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

У меня есть проект, который является своего рода набором тестов для нескольких устройств. Для каждого устройства я создал отдельный скрипт Python. Я положил все эти сценарии в пакет. Я могу импортировать этот пакет в другой скрипт Python и таким образом протестировать несколько устройств одновременно. С помощью файла конфигурации я могу установить, какие устройства я люблю тестировать (вместе с другой необходимой информацией для каждого устройства).

Ниже приведена упрощенная версия структуры проекта:

/app
  app.py
  app.config
  /scripts
    __init__.py
    commmon.py
    script1.py
    script2.py

приложение .py импортирует script1 и script2 из пакета scripts. Внутри пакета есть модуль common.py с некоторыми методами, используемыми всеми скриптами в пакете.

Давайте возьмем script1.py в качестве примера. Обычно я импортировал бы модуль common в этом скрипте следующим образом:

# Script1.py

from common import method1

Но поскольку script1 является частью пакета, и этот пакет импортируется в app.py, это выдает ошибку, когда app.py загружает пакет:

Traceback (most recent call last):
  File "app.py", line 4, in <module>
    import scripts.script1 as script1
  File "/home/kees/Sources/app/script/script1.py", line 4, in <module>
    from common import method1
ModuleNotFoundError: No module named 'common'

Чтобы решить эту проблему, я изменил импорт в script1.py на:

# script1.py

from .common import method1

Хорошо, это работает нормально. Но потом я подумал, может быть, мне нравится использовать script1.py в качестве отдельного скрипта. Например, если мне нравится сосредоточиться на тестировании только одного устройства. Но с новым оператором импорта это невозможно, потому что когда вы запускаете script1.py из командной строки, вы получаете ошибку:

Traceback (most recent call last):
  File "scripts/script1.py", line 6, in <module>
    from .common import common_method
ModuleNotFoundError: No module named '__main__.common'; '__main__' is not a package

Чтобы преодолеть эту проблему, я должен go вернуться к первоначальному импорту заявление в script1.py. Но тогда импорт пакета scripts в app больше не будет работать ...

Так что я должен сделать, чтобы иметь возможность использовать script1 из пакета (таким образом, импортировать пакет в app.py) и возможность использовать script1 напрямую. Единственное решение, которое я могу придумать, - это (и это работает):

# script1.py
if __name__ == '__main__':
    from common import method1
else:
   from .common import method1

Но мне это не кажется очень питонным c способом сделать это. Другое решение - не использовать пакет для всех сценариев, а поместить все файлы, включая app.py, в один каталог. Но это делает структуру менее ясной. И я бы лучше не связывался с путем python.

Есть предположения? Мне интересно, что вы думаете об этом.

...