← Назад к вопросам

Что такое циклический импорт в Python?

2.0 Middle🔥 181 комментариев
#DevOps и инфраструктура#Django

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Циклический импорт в Python

Циклический импорт (circular import) — это ситуация, когда два или более модуля пытаются импортировать друг друга, прямо или косвенно, создавая замкнутый цикл зависимостей. Это одна из распространённых проблем в больших проектах, которая может привести к ошибкам ImportError, AttributeError или неопределённому поведению программы.

Как это происходит

Представьте ситуацию:

# module_a.py
import module_b

def function_a():
    return module_b.function_b()
# module_b.py
import module_a

def function_b():
    return module_a.function_a()

Если вы попытаетесь импортировать одно из этих модулей, Python встретится с проблемой: при загрузке module_a он попытается загрузить module_b, а module_b попытается загрузить module_a, которая ещё не полностью инициализирована.

Примеры проблем

# app.py
from module_a import function_a

function_a()  # AttributeError: module 'module_b' has no attribute 'function_b'

Решения

1. Отложенный импорт (Lazy import)

# module_a.py
def function_a():
    import module_b  # Импорт внутри функции
    return module_b.function_b()

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

2. Импорт в конце модуля

# module_a.py
def function_a():
    return module_b.function_b()

import module_b  # Импорт после определения функций

3. Рефакторинг структуры

Лучший подход — вынести общий код в третий модуль:

# common.py
def shared_function():
    pass

# module_a.py
from common import shared_function

# module_b.py
from common import shared_function

4. Импорт типов в if TYPE_CHECKING блоке

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    import module_b

def function_a(b: "module_b.TypeB"):
    pass

Как избежать циклических импортов

  • Соблюдайте слоистую архитектуру (domain → application → infrastructure)
  • Используйте dependency injection вместо прямых импортов
  • Раннее выявление: запустите статические анализаторы (pylint, flake8)
  • Тестируйте импорты модулей отдельно

Циклические импорты — признак неправильной архитектуры. Их наличие говорит о необходимости рефакторинга.

Что такое циклический импорт в Python? | PrepBro