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 :

UnboundLocalError: local variable 'k_dest' referenced before assignment


Sujet :

Python

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 252
    Points : 85
    Points
    85
    Par défaut UnboundLocalError: local variable 'k_dest' referenced before assignment
    Bonjour à tous,
    la fonction appelée coupon_wrapper_production import un module parse_coupon_csv_production (dans ce module j'ai la variable k_dest).
    le premier passage dans la function est successful mais durant le deuxieme j'ai cette erreur:

    Traceback (most recent call last):
    File "C:\Project\code\coupon_wrapper_production.py", line 22, in <module>
    parse_csv(filename,security=False)
    File "C:\Project\code\parse_coupon_csv_production.py", line 91, in parse_csv
    else: dct['Dest'].append(k_dest)
    UnboundLocalError: local variable 'k_dest' referenced before assignment
    >>>

    qu'est ce qui s'est passé?

    Merci

    Billie

  2. #2
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Sans voir le code, c'est difficile à dire; comme le message l'indique cette exception se produit lorsque l'on essaie d'accéder au contenu d'une variable à laquelle on n'a encore rien assignée.
    Une cause fréquente est lorqu'on oublie de déclarer un accès à une variable globale dans une fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    x = 0
    def f():
       global x
       print x
       x = 1
       print x
    Dans cet extrait, si on oublie le "global x", on obtient une "UnboundLocalError" sur le premier print x, car dans la fonction f, x est considéré comme une variable locale à cause de l'assignation qui suit.

  3. #3
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    comme le message l'indique cette exception se produit lorsque l'on essaie d'accéder au contenu d'une variable à laquelle on n'a encore rien assignée.
    Pas tout à fait, l'exception est levée à la première tentative de l'affectation d'une variable même si celle-ci existe déjà dans l'espace de noms global.
    Un simple accès ne lève pas d'exception.

    Dans cet extrait, si on oublie le "global x", on obtient une "UnboundLocalError" sur le premier print x, car dans la fonction f, x est considéré comme une variable locale à cause de l'assignation qui suit.
    Même chose, l'erreur n'est pas émise sur le "print x" mais sur le "x = 1"

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 252
    Points : 85
    Points
    85
    Par défaut
    Salut a tous,
    le premier module qui fait appel a la function:

    from parse_coupon_csv_production import *


    year_range=range(2002,2008,1)
    quarter_range=range(1,5)

    for i in year_range:
    for j in quarter_range:
    print 'Origin_and_Destination_Survey_DB1BCoupon_'+str(i)+'_'+str(j)+'.csv'
    filename='Origin_and_Destination_Survey_DB1BCoupon_'+str(i)+'_'+str(j)+'.csv'

    parse_csv(filename,security=False)
    ensuite la function parse_csv est la suivante:


    def parse_csv(filename,security):

    import cPickle,time,sys

    data_path='C:/Project/data/'

    t0=time.time(); print; print 'Opening file: '+filename
    f=open(data_path+filename,'r')
    print 'Done. '+str(time.time()-t0)+' seconds to open file'

    if security: print; print 'Running in test mode.'; print; max_count=10000000
    else:
    max_count=0; print; print 'Counting number of lines in dataset'
    for j in f: max_count=max_count+1

    print 'Done. Number of lines of data: '+str(max_count)
    time.sleep(5)
    f.close()

    t01=time.time(); print; print 'Re-opening file: '+filename
    f=open(data_path+filename,'r')
    print 'Done. '+str(time.time()-t01)+' seconds to re-open file'

    t1=time.time(); key_list=[]
    for i in f:
    key_list_raw=i.split('"')[1:-1]
    for j in key_list_raw:
    if j!=',': key_list.append(j)
    else: pass
    break

    print; print 'List of variables in dataset: ('+str(len(key_list))+')'; print

    for i in key_list: print i

    retain_keys=['ItinID','Year','Quarter','Origin','Dest','RPCarrier','Passengers']

    print; print 'Retaining following variables: ('+str(len(retain_keys))+')'; print

    for i in retain_keys:
    if i in key_list: print i+' (found)'
    else: print i+'(not available)'; sys.exit(0)
    print

    dct={}
    for i in retain_keys: dct[i]=[]

    large_carriers={'Southwest':'WN','American':'AA','Continental':'CO',\
    'Delta':'DL','Northwest':'NW','TWA':'TW',\
    'United':'UA','US Airways':'US'}

    print 'Retaining following large carriers: ('+str(len(large_carriers.keys()))+')'; print
    for i in large_carriers.keys(): print i; print

    count=0; top_count=max_count/100; print; print 'Parsing data. Percentage completed: '; print count/top_count
    for i in f:
    a=i.split(',')[:-1]
    k=[eval(j) for j in a]

    if (k[key_list.index('SeqNum')]==1) and (k[key_list.index('RPCarrier')] in large_carriers.values()):
    coupons_new=k[key_list.index('Coupons')]; k_first=k[:]

    if k[key_list.index('Break')]=='X': count_break=1
    else: count_break=0

    for j in f:
    b=j.split(',')[:-1]
    l=[eval(m) for m in b]

    if l[key_list.index('SeqNum')]==coupons_new:
    if l[key_list.index('Break')]=='X': count_break=count_break+1; k_final_dest=l[key_list.index('Dest')][:]
    break
    else:
    if l[key_list.index('Break')]=='X': count_break=count_break+1; k_dest=l[key_list.index('Dest')][:]
    else: pass
    count=count+1

    if (count_break==2) and (k_first[key_list.index('Origin')]==k_final_dest):
    for n in retain_keys:
    if n!='Dest': dct[n].append(k_first[key_list.index(n)])
    else: dct['Dest'].append(k_dest)
    else: continue

    count=count+1

    if security:
    if count==1000: break
    else: pass
    else: pass

    if (count/top_count)==float(count)/float(top_count): print count/top_count

    print; print 'Done. '+str(time.time()-t1)+' seconds to parse data'
    print; print 'Number of flights (single): '+str(len(dct[dct.keys()[0]]))
    print 'Number of lines read: '+str(count)+' (total number = '+str(max_count)+')'

    t2=time.time()
    pickle_filename='coupon_'+filename.split('_')[-2:][0]+'_'+filename.split('_')[-2:][1][0]
    print; print 'cPickling dictionary: '+pickle_filename
    g=open(data_path+pickle_filename,'w')
    cPickle.dump(dct,g)
    g.close()
    print 'Done. '+str(time.time()-t2)+' seconds for cPickling'; print

    f.close()

    return
    une fois que je lance la le module coupon_wrapper_production.py, le premier fichier traité se fait sans probleme mais une fois que le module repasse dans la fonction parse_csv une deuxieme fois, j'obtiens l'erreur:

    Traceback (most recent call last):
    File "C:\Project\code\coupon_wrapper_production.py", line 22, in <module>
    parse_csv(filename,security=False)
    File "C:\Project\code\parse_coupon_csv_production.py", line 91, in parse_csv
    else: dct['Dest'].append(k_dest)
    UnboundLocalError: local variable 'k_dest' referenced before assignment
    >>>

    merci d'avance
    Billie

  5. #5
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    Plusieurs choses :

    1. Mélanger du code avec des explications sans formatage rend illisible le message
    2. Utilise la mise en forme automatique pour tout code posté (bouton #)
    3. On t'a déjà donné des pistes sur l'origine de l'erreur, cherche un peu par toi même

  6. #6
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Citation Envoyé par mchk0123 Voir le message
    Pas tout à fait, l'exception est levée à la première tentative de l'affectation d'une variable même si celle-ci existe déjà dans l'espace de noms global.
    Un simple accès ne lève pas d'exception.
    [...]
    Même chose, l'erreur n'est pas émise sur le "print x" mais sur le "x = 1"
    C'est peut-être une question de vocabulaire, mais l'erreur est bien levée sur la première tentative d'accès ("print x"), pas sur l'assignation; mais elle n'est levée que si une assignation suit; c'est toute la subtilité de cette erreur. L'assignation crée une variable locale dans le bloc lexical courant, la portée de cette variable comprend les instructions qui précèdent l'assignation dans le bloc courant. C'est assez troublant vu que, lorsqu'une variable globale du même nom existe, c'est une instruction qui suit dans le texte du programme qui cause une exception dans le code qui précède, mais c'est bien ce qui se passe.

    D'ailleurs ceci est la cause d'une limitation malheureuse dans python: il n'est possible de modifier qu'une variable locale (par défaut) ou globale (grâce au mot-clé "global"), pas une variable d'une autre portée englobante.

  7. #7
    Membre éclairé Avatar de mchk0123
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    816
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 816
    Points : 844
    Points
    844
    Par défaut
    mais l'erreur est bien levée sur la première tentative d'accès ("print x"), pas sur l'assignation; mais elle n'est levée que si une assignation suit
    Effectivement c'est une question de vocalubaire, pour ma part, le préfère dire que l'exception est émise sur l'affectation (car sans sa présence il n'y a pas d'exception), mais que à son affichage elle pointe sur la ligne ou à lieu le print.

    Etant donné que l'exception levée est d'ordre sémantique et qu'elle lie 2 lignes de codes en conflit, les 2 approches se valent.

    D'ailleurs ceci est la cause d'une limitation malheureuse dans python: il n'est possible de modifier qu'une variable locale (par défaut) ou globale (grâce au mot-clé "global"), pas une variable d'une autre portée englobante.
    Tout à fait d'accord, je résumerai que le comportement de Python est de résoudre l'évaluation de symboles dans le contexte local d'abord puis le contexte global à défaut ; alors que c'est toujours le contexte local qui est utilisé lors de l'affectation de symboles (sauf instruction 'global').

Discussions similaires

  1. local variable 'z' referenced before assignment
    Par djidji22 dans le forum Tkinter
    Réponses: 1
    Dernier message: 08/06/2012, 11h50
  2. Aide sur erreur variable referenced before assignment
    Par steph70 dans le forum Tkinter
    Réponses: 8
    Dernier message: 15/10/2009, 08h16
  3. Bug eclipse ? Local Variable is never read est à ignore
    Par jlong dans le forum Eclipse Java
    Réponses: 3
    Dernier message: 18/09/2007, 16h34
  4. erreur:The local variable may not have been initialized
    Par wiss20000 dans le forum Langage
    Réponses: 7
    Dernier message: 22/03/2007, 15h18
  5. Réponses: 2
    Dernier message: 20/09/2006, 18h10

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