Рубрики
Без рубрики

Структура проекта Python

Обновление – Обновленная версия этого проекта здесь – https: //github.com/unfor19/python-project/wiki … Tagged с помощью Python, Tuperial, Guide, Murdeal.

Обновление – Обновленная версия этого проекта здесь – https://github.com/unfor19/python-project/wiki

К концу этого поста в блоге вы сможете:

  • Создать хорошо структурированный проект Python
  • Используйте относительный и абсолютный импорт в проекте Python
  • Вызовать конкретный модуль из командной линии (терминал)

Ссылка на репозиторий GitHub – Unfor19/Python-Project

Структура проекта Python, относительный импорт, абсолютный импорт, пакеты и модули. Давайте сделаем это проще.

Начиная

Выполнение модулей из корневого каталога проекта (пакет верхнего уровня)

  • main.py
  meirgabay@~/python-project (master)$ python main.py
  My Path: python-project/main.py
  Insert your name: willy
  Hello willy


  meirgabay@~/python-project (master)$ python -m appy
  My Path: python-project/appy/__main__.py
  Insert your name: willy
  Hello willy
  • appy/core/app.py
  # Contains relative imports - `..utils.message`
  meirgabay@~/python-project (master)$ python appy/core/app.py
  Traceback (most recent call last):
    File "appy/core/app.py", line 1, in 
      from ..utils import message
  ImportError: attempted relative import with no known parent package


  meirgabay@~/python-project (master)$ python -m appy.core.app
  My Path: python-project/appy/core/app.py
  Insert your name: willy
  Hello willy
  • Appy/utils/message.py
  # Doesn't contain relative imports, so no exceptions were raised
  meirgabay@~/python-project (master)$ python appy/utils/message.py
  My Path: python-project/appy/utils/message.py

  meirgabay@~/python-project (master)$ python -m appy.utils.message
  My Path: python-project/appy/utils/message.py

Вопросы и ответы (Q & A)

Проект, пакеты, модули и сценарии, что они?

  • Проект – каталог, также известный как пакет верхнего уровня, который содержит пакеты и модули
  • Пакет (в проекте) – каталог, который содержит модули и/или пакеты (подзадачи)
  • Скрипт – сценарий Python ( .py ), который можно исключить из терминала
  • Модуль – сценарий Python ( .py ), который может быть импортирован с помощью Импорт и от

Как насчет пакетов, которые не являются частью проекта?

  • Пакет (встроенный) – пакет, который поставляется с Python и может быть импортирован с помощью Импорт и от
  • Пакет (PIP) – пакет, который установлен с Pip и может быть импортирован с Импорт и от Анкет Подумайте об этом, PIP выступает за Упаковка Я nstaller для P yton

Как им импортировать пакеты и модули, которые я создал?

  • Пакеты и модули Python Project могут быть импортированы с помощью Относительные пути из любого модуля, который Часть того же проекта Анкет Пример доступен в appy/core/app.py

  • Если вы собираетесь импортировать пакет или модуль, который является Не часть того же проекта , вам придется использовать Абсолютные пути Анкет Это можно сделать с ImportLib , см. Это Stackoverflow Ответ Анкет

Нужен ли мне файл __init__.py?

  • Короткий ответ – нет
  • В предыдущих версиях Python вы должны были создать __init__.py Файл в каждом каталоге, который вы хотите импортировать в качестве пакета, их называли обычные пакеты Анкет Из версии 3.3+ это больше не требуется – Неявные пакеты пространства имен , пакеты без __init__.py Файл называется Пакеты пространства имен Анкет

Почему относительный импорт поднимает проблему в пилинте?

Ошибка – Попытка относительного импорта за пределами верхнего уровня PackagePylint (относительный уровень Beyond-Top)

  • Короткий ответ – Я не знаю
  • Все, что я могу сказать, это то, что это не происходит с Flake8

Можно ли вызвать функцию из терминала?

  • Короткий ответ – это зависит

  • Попытка вызвать функцию из терминала, например appy.core.app.main () , поднимет исключение ModulEnotFound. Пакет должен быть импортирован до вызывая одну из его функций.

  meirgabay@~/python-project (master)$ python -m appy.core.app.main
  /Users/meirgabay/.pyenv/versions/3.8.2/Python.framework/Versions/3.8/bin/python: Error while finding module specification for 'appy.core.app.main' (ModuleNotFoundError: __path__ attribute not found on 'appy.core.app' while trying to find 'appy.core.app.main')
  • Поскольку вы не можете вызвать main () прямо из терминала, вызывая его из Если __main__ Блок позволяет выполнять его из терминала. Можно передать аргументы, но это немного уродливое, Прочитайте документы Чтобы узнать, как. Следующий пример пытается выполнить модуль appy.core.app , что, в свою очередь, называют его Если __main__ блокировать
  meirgabay@~/python-project (master)$ python -m appy.core.app
  My Path: python-project/appy/core/app.py
  Insert your name: willy
  Hello willy
  • Если Pwd является подкаталогом проекта, такой как Python-Project/Appy Попытка выполнить модуль, который содержит относительный импорт, поднимет исключение ниже. Помните, ваш Pwd Всегда должен быть корневым каталогом проекта, в данном случае это Python-Project Анкет
  # PWD is `appy`
  meirgabay@~/python-project/appy (master)$ python -m core.app

  Traceback (most recent call last):
    File "/Users/meirgabay/.pyenv/versions/3.8.2/Python.framework/Versions/3.8/lib/python3.8/runpy.py", line 193, in _run_module_as_main
      return _run_code(code, main_globals, None,
    File "/Users/meirgabay/.pyenv/versions/3.8.2/Python.framework/Versions/3.8/lib/python3.8/runpy.py", line 86, in _run_code
      exec(code, run_globals)
    File "/Users/meirgabay/python-project/appy/core/app.py", line 1, in 
      from ..utils import message
  ValueError: attempted relative import beyond top-level package
  • Это не происходит при вызовах Сообщение , так как Сообщение не использует относительный импорт
  meirgabay@~/python-project/appy (master)$ python utils/message.py
  My Path: python-project/appy/utils/message.py


  meirgabay@~/python-project/appy (master)$ python -m utils.message
  My Path: python-project/appy/utils/message.py
  • Вызов функции из терминала также возможна с помощью -c флаг. Сюрприз, можно провести аргументы более интуитивно понятным образом, например, app.main (my_arg1, my_arg2)
  meirgabay@~/python-project (master)$ python -c "import appy.core.app as app; app.main()"
  Insert your name: willy
  Hello willy

Каковы доступные флаги командной строки в Python?

Почему можно выполнить Python -m Appy?

Appy/__ main__.py Файл действует как Если __main__ Код фрагмент, но на пакетах. Это позволяет Appy пакет для выполнения с Python -m или с пробежка

meirgabay@~/python-project (master)$ python -m appy
My Path: python-project/appy/__main__.py
Insert your name: willy
Hello willy

Что такое Runpy и почему вы используете его в main.py?

Runpy Пакет предоставляет возможность запускать модули из модуля (сценарий Python).

main.py

import runpy


def main():
    # import a package, and pass all current global variables to it
    appy_package = runpy.run_module(mod_name="appy", init_globals=globals())

    # import the function script_path() from the submodule message, and execute it
    appy_package['message'].script_path(__file__)

    # execute the function main(), which is located in appy/__main__.py
    appy_package['main']()


if __name__ == "__main__":
    main()

Что за глобальные ()?

Официальное определение из док

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

Пример – развернуть/коллапс

meirgabay@~/python-project (master)$ python
Python 3.8.2 (default, Jun 30 2020, 19:04:41)
[Clang 11.0.3 (clang-1103.0.32.59)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': , '__spec__': None, '__annotations__': {}, '__builtins__': }

Почему у вас есть странный путь с Pyenv, когда вы запускаете Python?

В некоторых примерах вы, возможно, видели, что мой двоичный файл Python находится в

/Users/meirgabay/.pyenv/versions/3.8.2/Python.framework/Versions/3.8/bin/python

Это потому, что я использую Pyenv , официальное определение из документов

Pyenv позволяет легко переключаться между несколькими версиями Python . Это просто, ненавязчивая и следует за традицией UNIX одноцелевых инструментов, которые хорошо делают одну вещь.

  • Pyenv отлично подходит для проверки обратной совместимости

  • Переход на другую версию

  1. Установите соответствующую версию – Установка Pyenv 3.7.7
  2. Запустить Экспорт.7.7
  • Для повседневного использования
  1. Установите соответствующую версию – Установка Pyenv 3.8.2
  2. Добавить Экспорт.8.2 к вашему терминалу дольдо или _profile ( $ home/.bashrc , $ home/.bash_profile , $ Главная/.zshrc )

Примеры – развернуть/коллапс

meirgabay@~/python-project (master)$ export PYENV_VERSION=
meirgabay@~/python-project (master)$ pyenv versions
* system (set by /Users/meirgabay/.pyenv/version) # default OS Python
  3.7.7
  3.8.2
meirgabay@~/python-project (master)$ python --version
Python 2.7.16

# switching to a different version
meirgabay@~/python-project (master)$ export PYENV_VERSION=3.7.7
meirgabay@~/python-project (master)$ python --version
Python 3.7.7

# day to day use
meirgabay@~/python-project (master)$ source ~/.bash_profile
meirgabay@~/python-project (master)$ python --version
Python 3.8.2

Есть ли хорошая основа для создания Python CLI?

Где я могу найти хорошо структурированный проект Python?

  • SampleProject – Официальный проект Python Sample
  • Django – сложный проект Python
  • Запросы – Проект некомплекса Python

Последние слова

Я надеюсь, что этот пост в блоге помог вам понять, как создать хорошо структурированный проект Python, и, если это так, то сердце, хлопает, звезды и поделиться!

Оригинал: “https://dev.to/unfor19/python-project-structure-relative-imports-absolute-imports-packages-and-modules-let-s-make-it-simpler-6lk”