7
votes

Gérer les dépendances circulaires dans les modules Python?

C'est un cas à nouveau où je rencontre des cercles et je suis sur le point d'aller à l'état sauvage.

Je souhaite que Python analyse d'abord tous les fichiers, de sorte qu'il connaisse tous les identificateurs du début (je pense comme Java le fait).

J'ai un "Main.py" et une "Gui.py". Chaque fichier contient une classe, qui utilise la classe dans l'autre fichier. Quand j'essaie d'exécuter "Main.py", l'interprète importe "GUI", puis dans "Gui.py" IT importe "Main", puis il traite tout le module principal et dit: "Tee-hee, il n'y a pas de classe avec le nom donné dans Gui.py. "

Comment puis-je gérer des dépendances circulaires dans Python avec le minimum de Fuss ?


0 commentaires

3 Réponses :


17
votes

Je pensais étendre cela dans une réponse au lieu d'un commentaire.

Il convient de noter que circulaire Les importations sont généralement un signe de mauvais design : au lieu d'exiger la langue de votre conception, pourquoi ne pas changer cette conception?

Il y a façons autour de ce problème à Python :

  • La bonne option: refacteur Votre code ne doit pas utiliser les importations circulaires.
  • La mauvaise option: déplacez l'une de vos déclarations Importer à une autre portée.

    Mais non, vous ne pouvez pas pré-analyser les fichiers. Ce n'est pas la façon dont Python fonctionne et que si vous regardez comment fonctionne Python, il est assez évident pourquoi.


6 commentaires

Merci y'all. Les choses sont un peu plus claires pour moi, maintenant. C'est comme le motif observateur: une classe est le tuteur de l'autre (structurel, content de l'autre sens). La classe avec moins d'aperçu explique simplement aux auditeurs inscrites: "Euh, excusez-moi, j'ai changé." J'ai négligé que dans "Main.py", j'ai dû distinguer le code de la classe logique de l'application et le code qui obtient d'abord le programme à exécuter. J'ai mis une importation sous la classe et au-dessus du code freestanding.


Déplacement de l'importation vers la fin du fichier ne fonctionne pas. S'il est créé n'importe où dans la portée du module, il déclenchera une importation circulaire. Déplacer l'importation à une autre portée résoudra le problème (voir ma réponse ci-dessous)


@jcdyer corrigé et +1 à votre réponse pour donner plus de détails dans ce cas.


Dans un modèle de style ORM où ObjectA a de nombreux objetsB et objetb appartient à Objecta. C'est une dépendance cyclique commune qui semble avoir un sens total. Y a-t-il un bon moyen de supprimer cette dépendance de la conception?


@Zacwitte Option 2 - Déplacez l'importation cyclique quelque part où elle est exécutée uniquement après la fin de la première importation.


Merci. J'utilisais de. Importer des choses notation, qui refuse d'autoriser des importations circulaires du tout. Mais mettre l'importation à l'intérieur des méthodes qui utilisent cela fonctionne autour de cela.



3
votes

En général, les dépendances devraient être un arbre. Les dépendances circulaires ne sont pas résolvables.

Le moyen habituel de résoudre ce problème est de faire une "importation locale" du module requis à un niveau autre que l'espace de noms global.


0 commentaires

6
votes

Si vous ne pouvez pas éviter les importations circulaires, déplacez l'une des importations hors de portée du module, et dans la méthode / la fonction où elle a été utilisée.

filea.py p> xxx p>fileb.pyleight

def fileb_thing():
    import filea
    return filea.filea_thing() + " everyone."


0 commentaires