IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Erreur avec l'importation de module


Sujet :

Python

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 62
    Par défaut Erreur avec l'importation de module
    Bonjour,

    je m'adresse à vous aujourd'hui car j'ai un problème que je n'arrive pas a résoudre et que je ne comprend pas.
    Je travaille sur une appli dans le cadre de mon boulot pour gérer mon parc d'ordinateurs (c'est perso pour tuer le temps et apprendre du python ).
    l'appli fonctionnait correctement mais celle-ci commençant à être dense j'ai voulu la découper en plusieurs fichier "py" pour faciliter la navigation et le codage entre mes différentes fenêtres.
    sauf que depuis j'ai une erreur:

    << ImportError: cannot import name 'RootWindow' from partially initialized module 'mainwindow' (most likely due to a circular import) (C:\Users\Jean-Philippe\PycharmProjects\PARC_2\mainwindow.py) >>
    Voici une partie de mon code:

    Fichier execution :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    from mainwindow import RootWindow
     
    global winpcpal
    winpcpal = RootWindow()

    Fichier mainwindow :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    from tkinter import *
    from settingutil import SettingUtil
    from settingparc import SettingParc
     
     
    class RootWindow:
     
        def __init__(self):
     
            # Creation de la fenetre principale du logo et du titre
            self.master = Tk()
            # Creation de la frame principale et des sous-frames
            self.frame = Frame(self.master, width=1540, height=1360)
            self.frame.pack()
            self.lframe = Frame(self.frame, width=770, height=580)
            self.lframe.pack(side="left")
     
            # Bouton
            self.btn_user_settings = Button(self.lframe, command=self.sh_gestion_util)
            self.btn_user_settings.pack()
     
            self.flag = 0
            self.master.mainloop()
     
        def sh_gestion_util(self):
            global winsetutil
            if self.flag == 0:
                self.master.state('iconic')
                winsetutil = SettingUtil()
                self.flag = 1
                #self.settings.swin.mainloop()
            else:
                self.settings.swin.destroy()
                self.flag = 0
    Fichier settingutil:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    from tkinter import *
    from execution import winpcpal
     
    # Classe pour fenetre de gestion des utilisateurs
    class SettingUtil:
     
        def __init__(self):
            self.swin = Toplevel()
     
            # Creation de la frame principale
            self.frame = Frame(self.swin, width=1500, height=1500)
            self.frame.pack(padx=5, pady=5)
     
            self.swin.protocol("WM_DELETE_WINDOW", self.on_close)
     
     
        def on_close(self):
            self.swin.destroy()
            self.settings = winpcpal
            self.settings.deiconify()
    Voila, j'ai épuré un max pur ne mettre que l'utile le reste étant d'autres boutons , labels, etc ..
    et cela me et l'erreur dès que je tente d'importer ma variable globale "winpcpal".

    je comprend le principe de boucle de l'erreur mais je n'arrive pas à voir comment cela se produit dans mon code et encore moins comment le résoudre.
    (je ne suis qu'un débutant qui s'est trouvé un projet pour occuper son temps et apprendre ^^).
    Je suis disponible si des éclaircissement sont demandé .

    merci d'avance a vous et bonne journée !

  2. #2
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Salut,

    Pour moi le problème vient de from execution import winpcpal dans le fichier settingutil.py.

    On ne voit pas trop bien l'utilité de cette référence globale, mais, de toute façon, efface toutes les définitions de global de ton code, les global n'ont rien à faire dans de la programmation objet.

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par jeanfly Voir le message
    sauf que depuis j'ai une erreur

    << ImportError: cannot import name 'RootWindow' from partially initialized module 'mainwindow' (most likely due to a circular import) (C:\Users\Jean-Philippe\PycharmProjects\PARC_2\mainwindow.py) >>
    Import circulaire. Tu as "execution" qui importe "mainwindow" , "mainwindow" qui importe "settingutil" et "settingutil" qui importe "execution".

    Citation Envoyé par jeanfly Voir le message
    Voici une partie de mon code


    Citation Envoyé par jeanfly Voir le message
    et encore moins comment le résoudre.
    Tu crées un programme maitre qui importera X, Y et Z. Ensuite X pourra importer Y ou Z s'il en a besoin et etc mais aucun des trois ne peut importer le maitre.
    Exemple
    X.py
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #!/usr/bin/env python3
    # coding: utf-8
     
    def X(): print("X")
    import Y
    Y.Y()

    Y.py
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #!/usr/bin/env python3
    # coding: utf-8
     
    def Y(): print("Y")
    import X
    X.X()

    principal.py
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #!/usr/bin/env python3
    # coding: utf-8
     
    import X
    import Y
    X.X()
    Y.Y()

    Pour le reste, le mot clef "global" ne s'utilise pas comme tu le fais et surtout on n'utilise pas de variable globale sans en avoir une absolue nécessité ce qui n'est clairement pas le cas ici.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 62
    Par défaut
    Citation Envoyé par VinsS Voir le message
    Salut,

    Pour moi le problème vient de from execution import winpcpal dans le fichier settingutil.py.

    On ne voit pas trop bien l'utilité de cette référence globale, mais, de toute façon, efface toutes les définitions de global de ton code, les global n'ont rien à faire dans de la programmation objet.

    Merci pour ce commentaire, cela ne m'aide pas trop, j'avais déjà vu que l'utilisation de var globale n'est pas top mais avec peu de connaissance je fais "au mieux" et juste me dire que ca ne sert à rien ne m'aidera pas beaucoup.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 62
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Bonjour

    Import circulaire. Tu as "execution" qui importe "mainwindow" , "mainwindow" qui importe "settingutil" et "settingutil" qui importe "execution".





    Tu crées un programme maitre qui importera X, Y et Z. Ensuite X pourra importer Y ou Z s'il en a besoin et etc mais aucun des trois ne peut importer le maitre.
    Merci pour cela !!

    J'ai essayé de m'en aider pour mon code mais je ne comprend pas trop la hiérarchisation dans ton exemple :

    Mon fichier "execution" permet de lancer ma fenêtre maitre (mainwindow)

    Depuis cette dernière je peux obtenir une nouvelle fenêtre (settingutil)

    j'ai essayé de créer une méthode me retournant le nom de la fenêtre "mainwindow" afin que lorsque je ferme la fenêtre "settingutil" la fentre "mainwindow" s'affiche mais cela ne fonctionne pas.

    Dans settingutil.py
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    def get_wpcpal(self):
                       import execution
                       return execution.winpcpal
    je pensais pouvoir récupérer ensuite la variable dans ma méthode "on_close " du même fichier mais sans succès pou l'instant, je vais continuer a chercher car je pense bien que ma méthode n'est pas bonne mai cela va m'aider a avancer.

    J'aimerai surtout comprendre l'ordre dans lequel ton exemple fonctionne.

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par jeanfly Voir le message
    J'ai essayé de m'en aider pour mon code mais je ne comprend pas trop la hiérarchisation dans ton exemple :
    Il y a un maitre "principal" et 2 modules "X" et "Y". Les modules peuvent s'importer (presque) à loisir mais surtout ne peuvent pas importer "principal".
    Et c'est "principal" qui fait le lien et qui est exécuté.

    Pour ton cas, c'est à peu près pareil. Puisque c'est "execution" qui fait le lien, alors aucun module ne peut l'importer. Tu ne dois pas écrire import execution quelles que soient les circonstances. Et comme tu ne l'importes que pour avoir accès à la variable globale winpcpal, on retombe sur la remarque de VinsS qui, contrairement à ce que tu crois, t'aide beaucoup puisque ça te dit ce qu'il ne faut pas faire donc à toi ensuite de trouver le moyen de ne pas l'importer.
    Bon je ne connais pas tk (mon IHM de prédilection étant PyQt) mais d'après ce que je vois, winpcpal contient la RootWindow. Cette RootWindow crée ensuite une SettingUtil et cette SettingUtil utilise ensuite winpcpal (ie la RootWindow) pour lui faire un truc.
    Donc de là, pourquoi, quand tu crées ton SettingUtil tu ne lui passes pas la RootWindow à ce moment là (qui se trouve donc être "self" puisque cela se passe dans ledit RootWindow)?
    Ensuite ton SettingUtil recevant ce "RootWindow" en paramètre, le stocke dans un de ses attributs ce qui lui permettra de l'utiliser quand il en aura besoin (surtout qu'en plus il le stockait déjà dans ses attributs via self.settings = winpcpal !!!)

    Grosso-modo
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    class RootWindow:
    	def sh_gestion_util(self):
    		if self.flag == 0:
    			self.master.state('iconic')
    			winsetutil = SettingUtil(self)
    			self.flag = 1
    			#self.settings.swin.mainloop()
    		else:
    			self.settings.swin.destroy()
    			self.flag = 0
    		# if
    	# sh_gestion_util()
    # class RootWindow
     
    class SettingUtil:
    	def __init__(self, rootWindow):
    		self.__rootWindow=rootWindow
    		self.swin = Toplevel()
     
    		# Creation de la frame principale
    		self.frame = Frame(self.swin, width=1500, height=1500)
    		self.frame.pack(padx=5, pady=5)
     
    		self.swin.protocol("WM_DELETE_WINDOW", self.on_close)
    	# __init__()
     
    	def on_close(self):
    		self.swin.destroy()
    		self.__rootWindow.deiconify()
    	# on_close
    # class SettingUtil
    C'est une première façon.

    Une seconde (c'est celle que j'utilise en Qt) c'est de créer toutes les fenêtres en invisible dès le départ, puis ensuite selon les circonstances j'affiche telle ou telle fenêtre et masque telle ou telle autre. Ca évite de faire "création/suppression/création/suppression/création/suppression" à répétition. Et donc puisque les fenêtres sont crées dès le départ, elles se connaissent toutes (en fait je les range dans un dico et le dico est accessible à chacune) et peuvent alors s'interfacer.

    Et dans tous les cas, winpcpal disparait (enfin reste la variable qui reçoit le RootWindow mais n'est pas nécessaire d'être connue/importée ailleurs).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 62
    Par défaut
    Cool merci je suis arrivé a me dépatouiler et cela donne ca ^^

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    class RootWindow:
     def sh_gestion_util(self):
            if self.flag == 0:
                self.master.state('iconic')
                self.flag = 1
                self.winsetutil = SettingUtil(self)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class SettingUtil:
     
        def __init__(self, rootWindow):
            # recuperation de l'instance de RootWindow
            self.__rootWindow = rootWindow
     
        def on_close(self):
            self.swin.destroy()
            self.__rootWindow.master.deiconify()

    Merci beaucoup pour ton aide !!!

    Histoire d'abuser un peu j'ai une dernière question concernant ce passage de paramètre
    Grace a toi j'ai pu passer une instance d'un module à une autre mais je me demandais s'il était possible de le faire d'un sens puis de l'autre.
    comme par exemple pour passer le paramètre "flag" de "1" à "0" sur le "on_close" du "settingutil" puis le renvoyer sur le module "rootwindow".

    Je ne demande pas forcément la solution toute cuite mais à minima un aiguillage pour mes recherches futures ^^. Je pense que cela me servira pour lus tard ^^

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par jeanfly Voir le message
    comme par exemple pour passer le paramètre "flag" de "1" à "0" sur le "on_close" du "settingutil" puis le renvoyer sur le module "rootwindow".
    Bah oui, puisque ton SettingUI connait le RootWindow, il suffit de créer dans ledit RootWindow une méthode pour positionner son flag.
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    class RootWindow:
    	def setFlag(self, f): self.flag=f
    # class RootWindow
     
    class SettingUtil:
    	def __init__(self, rootWindow):
    		self.__rootWindow=rootWindow
    		self.swin = Toplevel()
     
    		# Creation de la frame principale
    		self.frame = Frame(self.swin, width=1500, height=1500)
    		self.frame.pack(padx=5, pady=5)
     
    		self.swin.protocol("WM_DELETE_WINDOW", self.on_close)
    	# __init__()
     
    	def on_close(self):
    		self.swin.destroy()
    		self.__rootWindow.deiconify()
    		self.__rootWindow.setFlag(1)
    	# on_close
    # class SettingUtil

    En plus, avec les property, tu peux même cacher une méthode derrière une affectation (en rendant alors l'attribut dédié à cette affectation privé cause conflit de nom)

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    class RootWindow:
    	def __setFlag(self, f): self.__flag=f
    	flag=property(None, __setFlag, None)
     
    	def __init__(self):
    		self.__flag=0
    	# __init__()
     
    	def sh_gestion_util(self):
    		if self.__flag: return
    		self.master.state('iconic')
    		self.__flag = 1
    		self.winsetutil = SettingUtil(self)
    	# sh_gestion_util()
    # class RootWindow
     
    class SettingUtil:
    	def __init__(self, rootWindow):
    		self.__rootWindow=rootWindow
    		self.swin = Toplevel()
     
    		# Creation de la frame principale
    		self.frame = Frame(self.swin, width=1500, height=1500)
    		self.frame.pack(padx=5, pady=5)
     
    		self.swin.protocol("WM_DELETE_WINDOW", self.on_close)
    	# __init__()
     
    	def on_close(self):
    		self.swin.destroy()
    		self.__rootWindow.deiconify()
    		self.__rootWindow.flag=1	# On croit que c'est une affectation mais en réalité ça appelle "MainWindow.__setFlag"
    	# on_close()
    # class SettingUtil

    Citation Envoyé par jeanfly Voir le message
    mais à minima un aiguillage pour mes recherches futures ^^
    Tutoriel Python (dans ma signature). Tout ça y est expliqué (chapitre XIV paragraphe 6.b pour le property)
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 62
    Par défaut
    Merci encore pour toutes ces infos ! c'est top je vais pouvoir m'en servir pour améliorer ma compréhension du langage grâce a tout ca !!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [2014] Erreur dans l'importation du module SQLPS
    Par NULL008 dans le forum Administration
    Réponses: 0
    Dernier message: 21/11/2019, 08h21
  2. Erreur importation de module
    Par Fooshi dans le forum Général Python
    Réponses: 3
    Dernier message: 06/09/2010, 09h53
  3. Débutant erreur avec import java.util.List
    Par speedyk62 dans le forum JSF
    Réponses: 7
    Dernier message: 14/07/2009, 00h24
  4. erreur avec withevents dans un module de classe
    Par patbou dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 20/12/2007, 04h32
  5. [py2exe] erreur avec le module pmw
    Par mythe dans le forum Py2exe
    Réponses: 1
    Dernier message: 24/07/2007, 13h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo