Как организовать импорты в коде согласно лучшим практикам?

Как решить проблему циклических импортов при попытке импортировать функцию из файла `apiparser.py` в `gui.py` и две переменные из `gui.py` в `apiparser.py`, которая приводит к `ImportError` из-за частично инициализированного модуля `imports`?
  • 5 декабря 2023 г. 11:10
Ответы на вопрос 2
Организация импортов в коде помогает улучшить читаемость, поддерживаемость и производительность программы. Вот несколько лучших практик для организации импортов:

1. Следуйте соглашениям стиля вашего языка программирования. В Python, например, принято придерживаться рекомендаций PEP 8.
2. Группируйте импорты в следующем порядке, разделив их пустыми строками:
   - Стандартные библиотеки
   - Сторонние библиотеки
   - Локальные/внутрипроектовые модули
3. Используйте абсолютный импорт вместо относительного, если это возможно, чтобы было ясно, из какого модуля происходит импорт.
4. Пытайтесь сохранять импорты минимальными; импортируйте только то, что нужно.
5. Избегайте импорта с помощью `*`, так как это затрудняет отслеживание того, откуда происходят определенные компоненты.
6. Сортируйте импорты внутри каждой группы (стандартные -> сторонние -> проектные).

Пример организации импортов в Python:

```python
# Стандартные библиотеки
import os
import sys

# Сторонние библиотеки
import requests
from flask import Flask

# Внутрипроектовые модули
from myproject.utils import utility_function
from myproject.models import ProjectModel
```

Чтобы решить проблему циклических импортов между `apiparser.py` и `gui.py`, можно использовать один из следующих подходов:

1. Периодические Импорты: Внутри функций или методов, импортируйте нужные компоненты непосредственно перед их использованием.

2. Структурная Перестановка: Переместите общий код, на который обе модули зависят, в отдельный модуль, например `shared.py`, а затем производите импорты из этого нового общего модуля. Это избавляет от прямой зависимости `gui.py` и `apiparser.py` друг от друга.

3. Инициализация Зависимостей: Используйте позднее связывание объектов, например, передавайте переменные как аргументы функций или инициализируйте их во время выполнения после загрузки обоих модулей.

4. Объединение Модулей: Если `apiparser.py` и `gui.py` тесно связаны, возможно стоит рассмотреть их объединение в один модуль, чтобы циклические импорты больше не были проблемой.

Пример периодического импорта внутри функции:

```python
# В файле gui.py

def some_gui_function():
    from apiparser import parse_api_response
    # Используйте parse_api_response здесь

# В файле apiparser.py

def parse_api_response():
    # В случае, если нужны переменные из gui.py
    from gui import some_variable
    # Используйте some_variable здесь
```

Пример инициализации зависимостей:

```python
# В файле gui.py

class GUI:
    def __init__(self):
        self.api_parser = None  # Инициализируется позже
def main_func():
    some code...

if __ name__ == "__main__":
    main_func()https://habr.com/ru/articles/702218/
Похожие вопросы