Как импортировать модули Python из одноуровневого каталога? - PullRequest
0 голосов
/ 25 января 2019

У меня есть проект Python (3.6.3), который имеет следующую структуру

setup.py
utils #python package
utils/constants.py
utils/name_reports.py
normalization #python package
normalization/resolve_name.py
categorization #python package
categorization/animal_categories.py

Вы можете найти исходный код здесь на github - https://github.com/techmango-org/python-import-resolution

Вот исходный код для utils/name_reports.py

import normalization.resolve_name as rn
import categorization.animal_categories as ac

test_name = 'DOGY'
resolved_name = rn.get_animal_name(test_name)

print('********ANIMAL CATEGORY IS:', ac.get_animal_score(resolved_name))

Когда я запускаю python utils/name_reports.py, я получаю следующее исключение

Traceback (most recent call last):
  File "utils/name_reports.py", line 1, in <module>
    import normalization.resolve_name as rn
ModuleNotFoundError: No module named 'normalization'

Я попытался решить эту проблему, установив текущий пакет в пакеты виртуального сайта env, запустив pip install ., но это означает, что для каждого локального изменения мне нужно запускать pip install --upgrade ., чтобы переместить мои локальные изменения в пакеты сайта.

Я использовал хак -m unittest, чтобы решить эту проблему. Проверьте этот скриншот

enter image description here

Но я не могу понять, какую разницу это создает. Вот точные вопросы -

  1. Как решить проблему импорта python в этой ситуации?
  2. Есть ли лучший подход к структурированию кода Python, чтобы мы не сталкивались с проблемой относительного импорта?
  3. Какую разницу создает -m unittest, которая решает эту проблему?

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Поскольку на SO уже есть много ответов *, я сосредоточусь на вопросе (2).О том, что является лучшей организацией кода:

|- setup.py
|- top_pkg_name
    |- __init__.py
    |- pkg1
        |- __init__.py
    |- pkg2
        |- __init__.py

(относительный) импорт выполняется следующим образом, изнутри module_2:

from ..pkg1 import module1 as m1

В качестве альтернативы, вы можете использовать абсолютный импорт,которые ссылаются на имя верхнего пакета:

from top_pkg_name.pkg1 import module1 as m1

В такой организации, когда вы хотите запустить какой-либо модуль в виде сценария, вы должны использовать флаг -m:

python -m top_pkg_name.pkg1.module1

По вопросу (3) я не уверен, но похоже, что модуль unittest добавляет папку к пути, позволяя импортировать напрямую.

* См .:

  1. Как импортировать скрипт Python из одноуровневого каталога?
  2. Модуль импорта Python из одноуровневой папки
0 голосов
/ 25 января 2019

Использовать операторы импорта:

from normalization import resolve_name
from categorization import animal_categories

Ваш код:

from normalization import resolve_name as rn
from categorization import animal_categories as ac

test_name = 'DOGY'
resolved_name = rn.get_animal_name(test_name)

print('********ANIMAL CATEGORY IS:', ac.get_animal_score(resolved_name))
...