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 :

problème UnboundLocalError dans une classe [Python 3.X]


Sujet :

Python

  1. #1
    Membre à l'essai
    Homme Profil pro
    collégien
    Inscrit en
    Juillet 2014
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : collégien
    Secteur : Enseignement

    Informations forums :
    Inscription : Juillet 2014
    Messages : 12
    Points : 14
    Points
    14
    Par défaut problème UnboundLocalError dans une classe
    Voici un code pour créer des pigeons (un peu comme turtle)
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    from math import *
    from tkinter import *
    class pigeon:
    	"""Canvas, coordonnée y, coordonnée x, degré
    Fonctions : __init__, left, right, forward, find_point, up, down, del_pointeur, pointeur"""
    	def __init__(self, canvas, coy = 250, cox = 250, degree = 0):
    		print(pigeon.__doc__)
    		if (degree < 0):
    			degree = -degree
    		degree = degree - degree//360 * 360
    		self.can = canvas
    		self.degree = degree
    		self.cox = cox
    		self.coy = coy
    		self.pointeur()
    		self.up = down
    	def find_point(self, pxl):
    		dir = self.degree // 90
    		tri = self.degree - dir * 90
    		cibley = pxl * cos(radians(self.degree))
    		ciblex = sqrt(pxl**2 - cibley**2)
    		if (tri % 4 == 0):
    			a = [-cibley, ciblex]
    		if (tri % 4 == 1):
    			a = [ciblex, cibley]
    		if (tri % 4 == 2):
    			a = [cibley, -ciblex]
    		if (tri % 4 == 3):
    			a = [-ciblex, -cibley]
    		return a
    	def left(self, d):
    		self.degree = self.degree + d
    		if (self.degree < 0):
    			self.degree = -self.degree
    		self.degree = self.degree - self.degree//360 * 360
    	def right(self, d):
    		self.degree = self.degree - d
    		if (self.degree < 0):
    			self.degree = -self.degree
    		self.degree = self.degree - self.degree//360 * 360
    	def forward(self, pxl):
    		a = self.find_point(pxl)
    		if (self.up == down):
    			self.can.create_line(self.coy, self.cox, self.coy+a[0], self.cox+a[1])
    		self.coy, self.cox = self.coy+a[0], self.cox+a[1]
    		self.pointeur()
    	def up(self):
    		self.up = up
    	def down(self):
    		self.up = down
    	def pointeur(self):
    		za = self.find_point(sqrt(10**2*2))
    		self.degree = self.degree + 135
    		zb = self.find_point(10)
    		self.degree = self.degree + 90
    		zc = self.find_point(10)
    		self.degree = self.degree + 135
    		self.point = self.can.create_polygon(za[0], za[1], zb[0], zb[1], zc[0], zc[1])
    	def del_pointeur(self):
    		del self.point
                    fen.delete(can, self.point
    voici l'erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    p = pigeon(can)
    Canvas, coordonnée y, coordonnée x, degré
    Fonctions : __init__, left, right, forward, find_point, up, down, del_pointeur, pointeur
    Traceback (most recent call last):
      File "<pyshell#38>", line 1, in <module>
        p = pigeon(can)
      File "C:\Users\fried_000\Desktop\dosssier\python\pigeon.py", line 17, in __init__
        self.pointeur()
      File "C:\Users\fried_000\Desktop\dosssier\python\pigeon.py", line 56, in pointeur
        za = self.find_point(sqrt(10**2*2))
      File "C:\Users\fried_000\Desktop\dosssier\python\pigeon.py", line 32, in find_point
        return a
    UnboundLocalError: local variable 'a' referenced before assignment
    voici une autre classe qui elle, marche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class p():
    	def __init__(self, x = 5):
    		self.l = 5
    		b = self.t(x)
    		print(b)
    	def t(self, x):
    		if (x % 3 == 0):
    			r = [0, 3]
    		if (x % 3 == 1):
    			r = [1, 4]
    		if (x % 3 == 2):
    			r = [2, 5]
    		return r
    Je ne comprends pas ce que j'ai mal fait...

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Dans votre fonction :

    Citation Envoyé par ofortuna Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    	def find_point(self, pxl):
    		dir = self.degree // 90
    		tri = self.degree - dir * 90
    		cibley = pxl * cos(radians(self.degree))
    		ciblex = sqrt(pxl**2 - cibley**2)
    		if (tri % 4 == 0):
    			a = [-cibley, ciblex]
    		if (tri % 4 == 1):
    			a = [ciblex, cibley]
    		if (tri % 4 == 2):
    			a = [cibley, -ciblex]
    		if (tri % 4 == 3):
    			a = [-ciblex, -cibley]
    		return a
    Si aucune des conditions n'est remplie (ce qui arrive lorsque 'tri' est un nombre à virgule flottante avec décimales non nulles), votre variable 'a' ne sera jamais initialisée et donc n'existera pas au moment d'exécuter return a.

    Résultat des courses :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Traceback (most recent call last):
      File "<pyshell#38>", line 1, in <module>
        p = pigeon(can)
      File "C:\Users\fried_000\Desktop\dosssier\python\pigeon.py", line 17, in __init__
        self.pointeur()
      File "C:\Users\fried_000\Desktop\dosssier\python\pigeon.py", line 56, in pointeur
        za = self.find_point(sqrt(10**2*2))
      File "C:\Users\fried_000\Desktop\dosssier\python\pigeon.py", line 32, in find_point
        return a
    UnboundLocalError: local variable 'a' referenced before assignment
    Je sais que c'est impressionnant d'éplucher un traceback quand on n'a pas l'habitude, mais c'est un mal nécessaire.

    Commencez toujours par la dernière ligne du message puis remontez le message à rebours tant que vous n'avez pas compris où se situe l'erreur.

    Ici, la dernière ligne dit :

    UnboundLocalError: local variable 'a' referenced before assignment

    traduit en français cela signifie grosso modo

    ErreurVariableLocaleNonDéclarée : la variable locale 'a' a été utilisée avant d'être initialisée.

    Est-ce que c'est plus clair comme ça ?

    @+.

  3. #3
    Membre à l'essai
    Homme Profil pro
    collégien
    Inscrit en
    Juillet 2014
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : collégien
    Secteur : Enseignement

    Informations forums :
    Inscription : Juillet 2014
    Messages : 12
    Points : 14
    Points
    14
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    dir = self.degree // 90
    		tri = self.degree - dir * 90
    		cibley = pxl * cos(radians(self.degree))
    		ciblex = sqrt(pxl**2 - cibley**2)
    		if (tri % 4 == 0):
    			a = [-cibley, ciblex]
    		if (tri % 4 == 1):
    			a = [ciblex, cibley]
    		if (tri % 4 == 2):
    			a = [cibley, -ciblex]
    		if (tri % 4 == 3):
    			a = [-ciblex, -cibley]
    		return a
    dir = 0(self.degree) // 90 donc 0
    tri = 0 - 0*90 donc 0
    tri % 4 = 0 donc [-cibley, ciblex]

    non?

  4. #4
    Membre expérimenté Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Points : 1 481
    Points
    1 481
    Par défaut
    Bonjour

    es-tu sur que le message d'erreur correspond au code que tu as posté ?
    J'ai quelques doutes.
    J'ai viré ce qui ne rentre pas en ligne de compte dans l'initialisation et les aspects tkinter, et il n'y a aucun message d'erreur.
    "La simplicité ne précède pas la complexité, elle la suit." - Alan J. Perlis
    DVP ? Pensez aux cours et tutos, ainsi qu'à la FAQ !

  5. #5
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par ofortuna Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    		dir = self.degree // 90
    		tri = self.degree - dir * 90
    		cibley = pxl * cos(radians(self.degree))
    		ciblex = sqrt(pxl**2 - cibley**2)
    		if (tri % 4 == 0):
    			a = [-cibley, ciblex]
    		if (tri % 4 == 1):
    			a = [ciblex, cibley]
    		if (tri % 4 == 2):
    			a = [cibley, -ciblex]
    		if (tri % 4 == 3):
    			a = [-ciblex, -cibley]
    		return a
    dir = 0(self.degree) // 90 donc 0
    tri = 0 - 0*90 donc 0
    tri % 4 = 0 donc [-cibley, ciblex]

    non?
    La formule m = a - b * (a // b) correspond à la formule du modulo : http://fr.wikipedia.org/wiki/Modulo_(informatique)

    Or, il se trouve que dans Python, la notation a modulo b s'écrit a % b

    Maintenant, ouvrez une console Python3 ou IDLE puis testez ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    >>> 125 % 90
    35
    >>> (125 % 90) % 4
    3
    >>> (125 % 90) % 4 == 3
    True
    >>> 125.123456 % 90
    35.123456000000004
    >>> (125.123456 % 90) % 4
    3.1234560000000045
    >>> (125.123456 % 90) % 4 == 3
    False
    Est-ce que vous comprenez mieux pourquoi vos tests ne sont jamais vérifiés ?

    Soit dit en passant, vous pouvez nettement optimiser le code de cette fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        def find_point(self, pxl, angle=None):
            if angle is None:
                angle = self.degree
            # end if
            cibley = pxl * cos(radians(angle))
            ciblex = sqrt(pxl**2 - cibley**2)
            tri = int(angle % 90) % 4
            return (
                [-cibley, ciblex],
                [ciblex, cibley],
                [cibley, -ciblex],
                [-ciblex, -cibley],
            )[tri]
        # end def
    @+.

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

Discussions similaires

  1. problème Select dans une classe
    Par sky88 dans le forum Servlets/JSP
    Réponses: 1
    Dernier message: 17/10/2010, 14h03
  2. Réponses: 8
    Dernier message: 12/04/2007, 11h32
  3. Problème Access Violation dans une classe
    Par randriano dans le forum C++Builder
    Réponses: 1
    Dernier message: 11/04/2007, 18h49
  4. problème d'accès dans une classe dérivée!
    Par chrono23 dans le forum C++
    Réponses: 47
    Dernier message: 10/10/2006, 11h22
  5. Problème dans une Classe
    Par Orbix dans le forum Langage
    Réponses: 8
    Dernier message: 02/10/2006, 14h52

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