Еще один вопрос об импорте python: я хочу, чтобы сценарий можно было импортировать и запускать как верхний уровень - PullRequest
0 голосов
/ 05 мая 2020

Я просмотрел кучу других ответов об импорте python, и ни один из них, похоже, не касается этой конкретной проблемы; также многие из них, похоже, датируются ~ 10 годами go, и ответы могут быть устаревшими. Допустим, у меня есть следующая структура каталогов:

one/
 |---first.py
 |---two/
      |----second.py
      |----three/
             |----third.py
             |----fourth.py

second.py вызывает third.py, а third.py вызывает 4th.py. Проблема в том, что мне нужно, чтобы second.py запускался сам по себе, а также мог быть вызван first.py.

Если second.py импортирует 3rd.py с использованием абсолютного импорта, from three import third, он будет работать нормально сам по себе, но при вызове first.py я получаю ModuleNotFoundError: no module named three.

Если second.py использует относительный импорт, from .three import third, он отлично работает при запуске first.py, но при попытке запустить second.py Я получаю ImportError: attempted relative import with no known parent package

Third.py может импортировать файл 4th.py с помощью относительного импорта, т.е. from . import fourth, поскольку мне не нужно, чтобы 3rd.py запускался напрямую.

Я также пробовал с __init__.py файлами в каждом из каталогов, и, похоже, это не имеет никакого значения.

Я придумал пару неуклюжих обходных путей:

  1. Имейте импорт в блоке if __name__ == "__main__":
  2. Создайте другой файл, second_caller.py, который существует только для вызова second.py
  3. Имейте две версии second.py , один для запуска сам по себе, а другой для вызова другими модулями.

Есть ли способ сделать импорт в s econd.py работает независимо от того, запущен ли он как __main__ или импортирован из другого места?

Я только что видел PEP366 (https://www.python.org/dev/peps/pep-0366/), и у него есть решение, которое по сути такое же, как мой вариант 1, импорт через if __name__ == "__main__": - это лучший вариант ?

...