Partage
  • Partager sur Facebook
  • Partager sur Twitter

Appelle des modules entre eux

Sujet résolu
    1 août 2023 à 11:02:50

    Bonjour à tous 

    J’ai un projet que je simplifie ici.
    Il contient :
    Un script principale -> main.py
    Deux modules -> modA.py et modB.py situés dans un dossier modules.

    modB.py utilise le module modA.py.

    Le problème est dans modB.py

    Si j’écris :

    from modA import *

    Cela fonctionne si « j’exécute » ce module modB.py. Mais cela ne marche pas quand j’exécute main.py (il ne trouve pas modA.py)

    Si j’écris :

    from modules.modA import *


    Cela fonctionne quand j’exécute main.py mais ne marche pas si « j’exécute » directement le module modB (il me dit qu'il ne connait pas "modules")

    Comment puis-je régler ce problème ?

    (J'ai créé un fichier __init__.py mais cela ne change rien)
    • Partager sur Facebook
    • Partager sur Twitter
      1 août 2023 à 11:45:24

      Bonjour,

      Dans main.py, il faut écrire

      os.chdir("chemin_vers_le_dossier_modules")
      from modA import *



      -
      Edité par Phil_1857 1 août 2023 à 11:49:42

      • Partager sur Facebook
      • Partager sur Twitter
        1 août 2023 à 11:45:48

        JérômePIERART a écrit:

        Comment puis-je régler ce problème ?

        Les dépendances circulaires sont difficiles à résoudre sauf à pousser ce qui est commun aux modules A et B dans un module C. On supprime alors la dépendance circulaire et C pourra être importé par A et B.

        Lorsqu'on exécute un script (il n'est pas "module" dans ce cas), il va chercher ses imports dans les sous-répertoires de celui du script => le contexte d'exécution d'un module (importé dans ce cas) est différent de son exécution en tant que script. Mais on peut modifier la liste des répertoires où cette recherche est faite, c'est à ça que servent PYTHONPATH et sys.path (voir la documentation).

        • Partager sur Facebook
        • Partager sur Twitter
          1 août 2023 à 12:03:15

          Merci pour vos réponses.

          Il n'y a pas de référence circulaire dans mon cas. modB utilise modA mais pas le contraire.
          Je voulais éviter de toucher à pythonpath ou sys.path, mais je vais m'y résigner !

          Quand au changement de répertoire, pourquoi pas !
          Mon programme principal nécessite de travailler dans un répertoire bien défini, mais je peux le rechanger juste après.

          Je teste tout ça et viendrais mettre un "résolu" si ça marche.




          • Partager sur Facebook
          • Partager sur Twitter
            1 août 2023 à 13:34:43

            JérômePIERART a écrit:

            Il n'y a pas de référence circulaire dans mon cas. modB utilise modA mais pas le contraire.
            Je voulais éviter de toucher à pythonpath ou sys.path, mais je vais m'y résigner !

            C'est ce que dit le titre et la description du problème est trop confuse pour l'infirmer.

            JérômePIERART a écrit:

            Quand au changement de répertoire, pourquoi pas !

            Si vous voulez qu'import modules.modA fonctionne lorsque modB est lancé comme script, ça ne va pas le faire...

            • Partager sur Facebook
            • Partager sur Twitter
              1 août 2023 à 21:35:04

              Bon finalement j'ai opté pour la solution du pythonpath. 

              En plus sous Pyzo c'est vraiment simple.

              Merci encore pour votre aide.

              • Partager sur Facebook
              • Partager sur Twitter
                10 août 2023 à 9:38:33

                Le mieux pour ça n'est pas de bidouiller à base de manipulation de path ou de changement de répertoire courant, c'est d'utiliser correctement le packaging Python.

                Si tes modules interfèrent entre-eux c'est que ce ne sont pas des modules indépendants mais des sous-modules d'un même paquet, il faut donc que les fichiers correspondent à cette structure.

                pkg/__main__.py

                from .modA import funcA
                
                print(funcA() + 1)
                

                pkg/modA.py

                from .modB import funcB
                
                def funcA():
                    return funcB() + 1
                
                if __name__ == '__main__':
                    print(funcA())
                

                pkg/modB.py

                def funcB():
                    return 10
                

                Ensuite c'est l'exécution de Python avec l'option -m qui permet d'exécuter les modules voulus. python -m pkg affichera 12 et python -m pkg.modA affichera 11.

                -
                Edité par entwanne 10 août 2023 à 9:39:53

                • Partager sur Facebook
                • Partager sur Twitter

                Appelle des modules entre eux

                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                • Editeur
                • Markdown