Python: Ошибка при импорте модулей

Я хочу разработать собственную библиотеку форм - pyqt6_forms.

введите сюда описание изображения

Вот код файлов: __ init __.py

from ._form import Form
from ._form_manager import FormManager

_form.py:


from typing import Callable
from ._form_manager import FormManager


class Form:
       """ Базовая форма для PyQt6-input-виджетов """

    def __init__(self, form_name: str,
                 default_value='',
                 converter: Callable = str,
                 error_handler: Callable = print,
                 form_manager: FormManager = None) -> None:

        self._form_name = form_name
        self._default_value = default_value
        self._converter = converter
        self._error_handler = error_handler
        self._form_manager = form_manager

        self.append_form_manager(form_manager)

    def get_value(self):
        """ Возвращает текущее значение поля """
        raise NotImplementedError('Невозможно получить значение, '
                                  'т.к. метод не определён')

    def set_value(self):
        """ Устанавливает текущее значение поля """
        raise NotImplementedError('Невозможно задать значение, '
                                  'т.к. метод не определён')

    def form_name(self):
        return self._form_name

    def default_value(self):
        return self._default_value

    def __change_form_manager(self, form_manager: FormManager):
        if form_manager:
            form_manager.append_form(self._form_name, self)
            self._form_manager = form_manager
        else:
            form_manager.remove_form(self._form_name)

    def append_form_manager(self, form_manager: FormManager):
        """ Добавляет форму в FormManager """
        if form_manager:
            self.__change_form_manager(form_manager)

    def remove_form_manager(self):
        """ Удаляет форму из FormManager """
        if self._form_manager:
            self.__change_form_manager(None)

_form_manager.py

from ._form import Form


class FormManager:
    def __init__(self) -> None:
        self.__forms_dict = {}
        self.__forms_list = []

    def append_form(self, form_name: str, form: Form):
        """ Добавляет форму в FormManager """
        if isinstance(form, Form):
            self.__forms_dict[form_name] = form
            self.__forms_list.append(form_name)
        else:
            raise TypeError(f'Must be {type(Form)}, not {type(form)} | '
                            f'"{form_name}": {form}')

    def append_forms_from_dict(self, forms_dict: dict[str, Form]):
        for form_name, form in forms_dict:
            self.append_form(form_name, form)

    def remove_form(self, form_name: str) -> Form | None:
        """ Удаляет форму из FormManager """
        removed_form = self.__forms_dict.pop(form_name, None)
        if removed_form:
            self.__forms_list.remove(form_name)
        return removed_form

    def forms_to_dict(self) -> dict[str, Form]:
        return self.__forms_dict.copy()

forms.py

from typing import Any, Callable

from PyQt6.QtWidgets import QLineEdit, QWidget

from ._form import Form
from ._form_manager import FormManager


class QLineEditForm(Form):
    """ Форма для `QLineEdit` """

    def __init__(self, *,
                 form_name: str,
                 parent: QWidget = None,
                 default_value='',
                 converter: Callable = str,
                 form_manager: FormManager = None) -> None:
        super().__init__(form_name, default_value=default_value,
                         converter=converter, form_manager=form_manager)
        self.qwidget = QLineEdit(parent)

    def get_value(self):
        return self._converter(self.qwidget.text())

    def set_value(self, value: Any):
        try:
            self.qwidget.setText(str(value))
        except Exception:
            self.qwidget.setText(str(self._default_value)
                                 if self._default_value
                                 else '')

    def restore_value(self):
        self.qwidget.setText(self._default_value)

Я активно использую TypeHinting, из-за этого мне приходится импортировать _form.py в _form_manager.py и _form_manager.py в _form.py, что приводит к исключению из-за циклического импорта...

Traceback (most recent call last):
  File "f:\PYTHON\GITHUB\pyqt6-forms\src\test.py", line 2, in <module>
    from pyqt6_forms import FormManager
  File "f:\PYTHON\GITHUB\pyqt6-forms\src\pyqt6_forms\__init__.py", line 1, in <module>
    from ._form import Form
  File "f:\PYTHON\GITHUB\pyqt6-forms\src\pyqt6_forms\_form.py", line 3, in <module>
    from ._form_manager import FormManager
  File "f:\PYTHON\GITHUB\pyqt6-forms\src\pyqt6_forms\_form_manager.py", line 1, in <module>
    from ._form import Form
ImportError: cannot import name 'Form' from partially initialized module 'pyqt6_forms._form' (most likely due to a circular import) (f:\PYTHON\GITHUB\pyqt6-forms\src\pyqt6_forms\_form.py)

Я долгое время не могу понять КАК ПРАВИЛЬНО СДЕЛАТЬ, чтобы не было никаких ошибок импорта, а то они уже в горле у меня сидят... Я пробовал делать такую же архитектуру проекта, как в selenium или loguru, но всё равно получал одно и то же исключение... Я ПРОСТО УЖЕ ВСЁ ПЕРЕПРОБОВАЛ, нужна профессиональная помощь)))

Если не сложно, продублируйте этот проект у себя, чтобы нагляднее было, у меня просто уже идей нет :(


Ответы (1 шт):

Автор решения: ganz

Суть в том, что ты из файла _form импортируешь файл _form_manager.py из которого ипоротируешь файл _form итд о чём интерпритатор и написал. Нужно убрать импорт из одного из двух файлов.

→ Ссылка