Problème utilisation instance de classe par un programme externe

Résolu/Fermé
NeoPython - Modifié le 30 oct. 2020 à 09:26
yg_be Messages postés 23399 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 17 décembre 2024 - 10 nov. 2020 à 20:31
Bonjour à tous

J'ai un problème d'utilisation des instances de classes dans une fonction qui est écrit dans un fichier externe.
J'ai fabriqué deux petits programmes de test pour mieux me faire comprendre.
Imaginez une classe "Rectangle" qui contient deux variables : "Longueur" et "Largeur"
Un Objet "Rectangle_Rouge" donnera donc les instances "Rectangle_Rouge.Longueur" et "Rectangle_Rouge.Largeur"
Les variables sont sous format IntVar() car je vais les utiliser sous forme de graphique "tkinter".

Je peux utiliser les instances de classe "Rectangle" sous différentes formes : par des fonction et par l'instruction exec(), sans problème tant que le programme est contenu dans un même fichier.

Voici le programme nommé Etude.py :

from tkinter import *
from Etude_suite import Modification_rectangle_suite

class Rectangle :
    def __init__(self):
        Longueur, Largeur = IntVar(), IntVar()
        Valeur_Initiale = "0"
        Longueur.set(Valeur_Initiale)  # Chargement valeur initiale
        self.Longueur = Longueur
        Largeur.set(Valeur_Initiale)  # Chargement valeur initiale
        self.Largeur = Largeur

def Modification_rectangle() :
    print(Rectangle_Rouge.Longueur.get())
    Rectangle_Rouge.Longueur.set(444)
    print(Rectangle_Rouge.Longueur.get())

    Nom_objet_a_modifier = "Rectangle_Rouge"
    Nom_variable_a_modifier = "Longueur"
    exec(Nom_objet_a_modifier + "." + Nom_variable_a_modifier + ".set(555)")
    print(Rectangle_Rouge.Longueur.get())

def Modification_rectangle_bis (Rectangle_Choisi) :
    print(Rectangle_Choisi.Longueur.get())
    Rectangle_Choisi.Longueur.set(666)
    print(Rectangle_Choisi.Longueur.get())

    Nom_objet_a_modifier = "Rectangle_Rouge"
    Nom_variable_a_modifier = "Longueur"
    exec(Nom_objet_a_modifier + "." + Nom_variable_a_modifier + ".set(777)")
    print(Rectangle_Choisi.Longueur.get())


# ------   DEBUT DU PROGRAMME PRINCIPAL ------
fenetre = Tk()

global Rectangle_Rouge
Rectangle_Rouge = Rectangle ()

print(Rectangle_Rouge.Longueur.get())
Rectangle_Rouge.Longueur.set(111)
print(Rectangle_Rouge.Longueur.get())

Nom_objet_a_modifier = "Rectangle_Rouge"
Nom_variable_a_modifier = "Longueur"
exec(Nom_objet_a_modifier + "." + Nom_variable_a_modifier + ".set(333)")
print(Rectangle_Rouge.Longueur.get())

Modification_rectangle()
Modification_rectangle_bis (Rectangle_Rouge)
Modification_rectangle_suite (Rectangle_Rouge)


Mon problème est que tout ce qui fonctionnait dans un fichier unique, ne fonctionne pas dans un fichier extérieur :
Voici ci dessous un fichier externe : Etude_suite.py
Pour être précis la ligne programme qui ne fonctionne pas est celle ci : exec(Nom_objet_a_modifier + "." + Nom_variable_a_modifier + ".set(999)",globals(),dico)
J'ai un défaut, NameError: name 'Rectangle_Rouge' is not defined

def Modification_rectangle_suite (Rectangle_Choisi) :
    print(Rectangle_Choisi.Longueur.get())
    Rectangle_Choisi.Longueur.set(888)
    print(Rectangle_Choisi.Longueur.get())

    Nom_objet_a_modifier = "Rectangle_Rouge"
    Nom_variable_a_modifier = "Longueur"
    dico = {}
    exec(Nom_objet_a_modifier + "." + Nom_variable_a_modifier + ".set(999)",globals(),dico)
    print(Rectangle_Choisi.Longueur.get())


Quelqu'un pourrait il me renseigner sur une solution de bon fonctionnement?
Avec tous mes remerciements.
A voir également:

2 réponses

yg_be Messages postés 23399 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 17 décembre 2024 Ambassadeur 1 556
30 oct. 2020 à 12:46
je n'ai pas testé, mais il me semble que, dans Etude_suite.py, la variable Rectangle_Rouge est inconnue.
ne devrais-tu pas écrire Nom_objet_a_modifier = "Rectangle_Choisi"?
2
Bonsoir et merci pour ta participation.

J'ai essayé avec Nom_objet_a_modifier = "Rectangle_Choisi", j'ai le même défaut.
De toute façon j'aurai besoin d'utiliser des formes chaines de caractères dans mon vrai programme ( Rectangle_Rouge , Rectangle_Bleu, Rectangle_Vert, ...)

Le plus fort, c'est que cela fonctionne tant que l'on ne quitte pas le programme principal (Etude.py) :
exec(Nom_objet_a_modifier + "." + Nom_variable_a_modifier + ".set(555)") dans la ligne 20

J'ai lu que la fonction exec() se comporte différemment dans les programmes externes, mais je ne vois pas comment l'écrire correctement.
0
yg_be Messages postés 23399 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 17 décembre 2024 1 556 > NeoPython
2 nov. 2020 à 18:20
as-tu essayé de déclarer tes variables globales dans un troisième fichier, que tu importes dans chacun des deux autres?
0
NeoPython > yg_be Messages postés 23399 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 17 décembre 2024
10 nov. 2020 à 20:17
Bonsoir
Merci pour la proposition, j'ai essayé avec un troisième fichier mais pas mieux.

Finalement je m'en suis sorti en remplaçant la ligne à problème par :

Instance_voulue = getattr(Rectangle_Choisi, Nom_variable_a_modifier) #Adresse instance partiellement paramétrable
Instance_voulue.set(999)
print(Rectangle_Choisi.Longueur.get())

Merci encore.
0
NeoPython > NeoPython
10 nov. 2020 à 20:21
Comment marque t'on problème résolu ?
0
yg_be Messages postés 23399 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 17 décembre 2024 1 556 > NeoPython
10 nov. 2020 à 20:31
comme tu n'es pas inscrit sur le site, peut-être via un lien dans le mail envoyé quand il y a une mise à jour?
je vais le faire pour toi.
0
dachiasse Messages postés 1709 Date d'inscription samedi 12 septembre 2020 Statut Membre Dernière intervention 13 mai 2021 149
5 nov. 2020 à 04:57
Salut,
C'est dommage d'utiliser
global
quand on sait (Swinnen) que l'utilisation de classes permet de ne plus l'utiliser.

Je ne comprends pas bien le problème, mais, tu as essayé sans tkinter ? Si tu fais de la prog modulaire (multi fichiers) il faut bien gérer les importations, or, dans tes codes, aucune trace de
import # fichier1, ...
0