Benutzer-Werkzeuge

Webseiten-Werkzeuge


python:circular_import
  • Import-Error wegen eines circular Imports

Für gewöhnlich bekommt man diese Meldung:

ImportError: cannot import name 'xyz' from partially initialized module 'abc' (most likely due to a circular import) (module in which the issue happens)

  • der Parser lädt Modul A
  • in A verweist Objekt A.1 auf ein Objekt B.1
  • B.1 ist in Modul B definiert
  • B.1. verweist auf ein Objekt A.2
  • A.2 ist in Modul A definiert

Das Problem ist, das der Parser versucht ein Modul A zu laden und dabei alle Abhängigkeiten aufzulösen und dazu B lädt bevor A komplett geladen ist.
B wiederum muss A laden, was bereits halb geladen ist und das resultiert in einer Loop.

  • das Objekt was auf B verweist muss in ein eigenes Modul gepackt werden
    • das Objekt ist dann in Modul C
    • Modul C verweist dann auf Modul B, welches auf Modul A verweist
    • damit gibt es keinen Kreis mehr

Circular Import wegen Typing

  • kann umgangen werden in dem das Prüfen der Typ-Klassen erst nach dem laden der kompletten Module erfolgt
  • das importieren der Pakete/Module die die Typen enthalten erst beim Type-Checking erfolgt
    • notwendig da sonst bereits durch den import (der Interpreter weiß ja nicht das es nur für Type-Annotation geladen wird) der Circular Error entsteht

from __future__ import annotation
from typing import TYPE_CHECKING

if TYPE_CHECKING:
   import whateverlib resulting else in circular import

rest of code

  • Der Import von annotations von
    __future__

    sorgt dafür das die Prüfung der Klassen die für Typing angegeben sind erst auf Existenz geprüft werden nach dem das Modul komplett geladen worden ist (also alle Klassen bekannt sind)

    • ab Python 3.10 ist das Standart-Verhalten und nicht mehr notwendig
  • TYPE_CHECKING ist eine Konstante, die nur dann True ist wenn Typen geprüft werden, das heißt die Bibliothek wird auch nur in diesem Moment geladen und verursacht somit keinen Circular Import
python/circular_import.txt · Zuletzt geändert: 2022/04/11 15:43 von root