Задать вопрос

Как вы боритесь с циклическими импортами в Python?

Слушайте люди, как вы боритесь с циклическими импортами в питоне?
На больших проектах это прям становится какой то большой проблемой если вы используете статические типы данных в аргументах функции. Давайте сразу пример:

main.py

from Article import Article
from User import User

if __name__ == '__main__':
    pass


User.py
from Article import Article

class User:
    def __int__(self, name: str):
        self.name = name

    def fetch_article(self) -> list[Article]:
        """
        Returns all the user's articles
        :return:
        """
        return [Article(), Article()]  # Just for example


Article.py
from User import User


class Article:

    def __int__(self, title: str, user: User):
        self.title = title
        self.user = user


Traceback (most recent call last):
File "/home/master/PycharmProjects/example/main.py", line 1, in
from Article import Article
File "/home/master/PycharmProjects/example/Article.py", line 1, in
from User import User
File "/home/master/PycharmProjects/example/User.py", line 1, in
from Article import Article
ImportError: cannot import name 'Article' from partially initialized module 'Article' (most likely due to a circular import) (/home/master/PycharmProjects/example/Article.py)


Собственно простая задача, есть статьи, есть пользователи которые их написали, и для примера мы хотим добавить
в модель пользователя метод который дергает все написанные им статьи.
Как цивилизованный человек я всегда указываю типы данных которые ожидаю на входе, и которые ожидаю на выходе.
Это нормальная практика, я пишу не на одном языке, и обычно это не вызывает проблем например в том же PHP ибо там есть магические __autoload.php который помогает избегать циклических импортов. Однако в питоне такой штуки нету.
А отказываться от явного указания типов аргументов я не хочу. Это дурной тон, грязный код, и ворох багов в будущем, да еще и призрение тестировщика... Короче хочу спросить у бородатых и опытных, как вы разруливаете данные проблемы в проекте? какие средства для этого есть? Ведь сказать что с точки зрения написания чистого кода, код выше неправильный нельзя.
  • Вопрос задан
  • 2799 просмотров
Подписаться 5 Простой Комментировать
Помогут разобраться в теме Все курсы
  • Нетология
    Python-разработчик: расширенный курс + нейросети
    12 месяцев
    Далее
  • Яндекс Практикум
    Python-разработчик
    10 месяцев
    Далее
  • Skillbox
    Профессия Python-разработчик + ИИ
    10 месяцев
    Далее
Решения вопроса 1
Vindicar
@Vindicar
RTFM!
Если речь идёт об импорте только ради type hinting, то typing.TYPE_CHEKING в помощь.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@yakov_the_kaktus
Попробуйте импортировать то, что вам надо локально:
def your_function_or_method():
     from User import User
     ...
Ответ написан
Комментировать
@gimntut
Я ориентируюсь на линтер PyCharm, он позволяет использовать типы до импортов
from typing import TYPE_CHECKING, List

def get_cat_list() -> List["Cat"]
  from animals import Cat

  return [Cat() for _ in range(3)]

if TYPE_CHECKING:
  from animals import Cat

Возможно mypy покажет на таком коде ошибку.
В данном примере pycharm подсветит ошибку, если забыть сделать импорт внутри функции.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
ITK academy Краснодар
от 220 000 до 300 000 ₽
ITK academy Краснодар
от 75 000 ₽
DimaTech Ltd Краснодар
от 140 000 до 140 000 ₽