Импорт PyCharm против интерпретатора

#python #import #pycharm

#python #импорт #pycharm

Вопрос:

Существует следующая структура проекта PyCharm:

 testImport
    target
        __init__.py
        script_1.py
        script_2.py
  

Содержимое следующее:

 #script_1.py
import datetime

now_ts = datetime.datetime.now()
  
 #script_2.py
from script_1 import now_ts

print('Now: {}'.format(now_ts))
  

PyCharm требует, чтобы я исправил строку импорта в script_2.py файле и использовал from target.script_1 import now_ts . Как только я пытаюсь выполнить ~/testImport: ./target/script_2.py , я получаю ModuleNotFoundError: No module named 'target' . Как возможно, что PyCharm предлагает неправильное решение или происходит что-то, о чем я не знаю?

Комментарии:

1. Это может быть частью компоновки PEP-8, поскольку рекомендуется использовать абсолютный импорт , а не относительный импорт

Ответ №1:

Предложение PyCharm, вероятно, связано с тем, что IDE считает, что ваша target папка является модулем. Наличие исполняемого скрипта в модуле считается антишаблоном. См. Мнение Гвидо Ван Россума по этому поводу.

Я -1 в этом и в любых других предлагаемых изменениях основного механизма. Похоже, единственным вариантом использования является запуск скриптов, которые находятся внутри каталога модуля, который я всегда рассматривал как антипаттерн. Чтобы заставить меня передумать, вам нужно убедить меня, что это не так.

Я предлагаю вам изменить структуру вашего проекта, чтобы сделать вашу основную логику в модуле, а исполняемый файл вне модуля, то есть:

 testImport
├── script_1.py
└── target
    └── my_logic.py
  

И в вашем script_1.py :

 from target.my_logic import now_ts
  

Примечание: Конечно, я просто использую вызов authority в качестве аргумента здесь. В вашем случае использования может быть лучше продолжить то, как вы разрабатываете. В этом случае просто отклоните предложение IDE.

Ответ №2:

Ключевым моментом является то, что когда вы запускаете свой скрипт по умолчанию python ./target/script_2.py , интерпретатор script_2 считается основным модулем и не позволяет вам найти верхнюю папку.

Вы можете запустить aviod следующими способами ModuleNotFoundError (только если вы четко понимаете, что делаете, не используйте в большом проекте):

  1. при ~/testImport запуске python -m target.script_2
  2. script_2.py добавьте в топ
 __package__ = "target.script_2"
  
  1. script_2.py добавьте в топ
 if __name__ == "__main__":
    import sys
    import os
    sys.path.insert(0, os.path.abspath(os.curdir))
  

войдите ~/testImport и запустите python ./target/script_2.py

Я был бы очень признателен, если бы кто-нибудь мог помочь мне исправить мой неестественный английский.