Python: exec et "nested function"?

Bonjour,
j’ai un probleme avec exec sur la fonction suivante:

def ToutSelection():
     if retour19.get()==1:
         for i in range(1,19):
                        command="{0}{1}{2}".format('retour',str(i),'.set(1)') 
                        command2="{0}{1}{2}".format('self.canvas_image',str(i),'fond.configure(bg="#7aa0f6")')
                        exec command
                        exec command2 

Mais j’ai une erreur:

    exec command 
SyntaxError: unqualified exec is not allowed in function 'ToutSelection' because it is a nested function

j’ai trouvé ça mais je ne comprends pas ce que je dois changer…?

Je précise j’utilise python 2.7 et pas python 3 en effet…

MErci :slight_smile:

D’après ce que je comprend de ce sujet, ta fonction ne peut pas utiliser exec car, faisant appel à des variables externe à elle, elle aquiert le statut de “nested”.
Je n’ai pas bien compris le concept, mais tu peux toujours essayer de mettre les variables “retour19” en paramètre de la fonction et de passer cette variable lors de l’appel.

Je n’ai pas reçu à reproduire l’erreur, mais avec un contexte un peu moins vague (notament sur les valeurs des variables retour1 à retour19), je pourrais sans doute t’aider.

Bonjour et merci de la réponse.
Alors mes variables retour1 à 18 sont liées à des cases à cocher (0 déselectionnée et 1 sélectionnée). Retour19 est liée à une case particulière permettant de cocher toutes les autres si sélectionnée.
Et l’histoire de rajouter in globals(), locals() comme dans le sujet que j’ai cité plus haut? Je n’ai pas bien compris cette histoire?
Merci en tout cas
Bonne journée

Je contourne le problème, mais pourquoi ne pas utiliser le très recommandé module subprocess ?

[quote=“seb-ksl, post:4, topic:70125, full:true”]Je contourne le problème, mais pourquoi ne pas utiliser le très recommandé module subprocess ?[/quote]Tout simplement car il ne s’agit pas d’executer un sous-processus, mais de manipuler les variables.
Je suis d’accord, ce n’est pas la meilleure façon de faire, mais là, le but est de faire fonctionner le truc si on le faire fonctionner autrement, on pourrait utiliser une liste ou un dictionnaire au lieu d’une série de variables, mais ce n’est pas du tout la question.

[quote=“totola, post:3, topic:70125”]Et l’histoire de rajouter in globals(), locals() comme dans le sujet que j’ai cité plus haut? Je n’ai pas bien compris cette histoire?[/quote]Je n’ai pas des compétences aussi avancée en Python, mais il me semble que locals() permet d’avoir la valeur de la variable pour le bloc courant (ta fonction), globals permet d’avoir la variable du module courant (du fichier).
En gros, tu devrais appeller globals () ['retour1'] au lieu de retour1, mais là encore, je ne suis pas sûr et je ne peux pas le tester.

Je veux bien contourner le problème, mais je ne vois pas comment faire avec subprocess? On ne peut lancer que des commandes shell?

MErci

Je crois que je viens juste de comprendre, tellement le code est bizarre.

@totola, tu confirmes : tu as une série de variables retour1-retour19 qui contiennent des cases à cocher Tkinter, et tu cherches à ce que le statut 1 (coché) de retour19 coche les 18 autres, c’est ça ?

Là les avis divergent. Parce que si ce que j’ai compris du problème de @totola est vrai, c’est une erreur de design qui (pour moi) prévaut complètement sur le problème d’exec qu’il rencontre. La première solution à envisager est effectivement une liste de variables, plutôt qu’une affreuse bidouille à base d’exec.

Pour info, @totola, ça te donnerait quelque chose comme ça :

retour = []
retour.append(ta_case_Tkinter_numero1)
[...]
retour.append(ta_case_Tkinter_numero19)
[...]

def ToutSelection():
    if retour[18].get() == 1:
        for i in range(18):
            retour[i].set(1)

Note que tes cases à cocher seront alors 0-indexées et non plus 1-indexées (ce qui est plus “propre”).

Oui seb-ksl…
En plus tu m’avais déjà corrigé quelque chose comme ça il y a un certain temps…
:innocent:

J’essaie de bien intégrer ça cette fois et je reviens s’il y a un problème!
Merci

Yes, je crois que j’ai bien compris cette fois

Pour te le prouver j’ai aussi du reprendre mes canvas… :wink:

self.canvas_image_fond=[None]
i=1
while(i<19):
       self.canvas_image_fond.append(Tkinter.Canvas(width = width_fond, height = height_fond, bg='white',bd=0,highlightthickness=0))
       self.canvas_image_fond[i].place(x=x_fond[i], y=y_fond[i], anchor='nw')
       i=i+1

Je te laisse deviner ce que j’avais fait avant… :grin:

Bon par contre tu dis que c’est plus propre d’indexer de 0 à 18, j’ai pas respecté pour l’instant je préfère garder mes numéros de 1 à 19

Merci beaucoup en tout cas

Hum j’ai un autre problème, j’ouvre un nouveau fil :slight_smile: