2010-10-29 6 views
4

Je reçois un UnboundLocalError car j'utilise une valeur de modèle dans une instruction if qui n'est pas exécutée. Quelle est la manière standard de gérer cette situation?UnboundLocalError: variable locale ... référencée avant l'affectation

class Test(webapp.RequestHandler): 
    def get(self):  
     user = users.get_current_user() 
     if user: 
      greeting = ('Hello, ' + user.nickname()) 
     else: 
      self.redirect(users.create_login_url(self.request.uri)) 
... 

     template_values = {"greeting": greeting, 
         } 

Erreur:

UnboundLocalError: local variable 'greeting' referenced before assignment 
+3

Y at-il une raison quelconque vous ne peut-il pas simplement faire "greeting = None" (ou une valeur par défaut raisonnable) avant le bit "if ... else"? –

+0

Merci. Je ne savais pas. – Zeynel

+1

Je ne connais pas webapp, mais je pense que vous voulez faire 'return self.redirect ...' de toute façon. –

Répondre

3

Juste Commutateur:

class Test(webapp.RequestHandler): 
    def err_user_not_found(self): 
     self.redirect(users.create_login_url(self.request.uri)) 
    def get(self):  
     user = users.get_current_user() 
     # error path 
     if not user: 
      self.err_user_not_found() 
      return 

     # happy path 
     greeting = ('Hello, ' + user.nickname()) 
     ... 
     template_values = {"greeting": greeting,} 
+0

Merci pour la réponse. J'ai utilisé 'greeting = None' pour l'instant; mais quand je suis prêt à déployer l'application, je peux utiliser cette version. Que fait «retour»? Pourquoi est-ce nécessaire? – Zeynel

+0

@Zeynel Il quitte la routine, sinon l'interpréteur continuera à exécuter toutes les instructions suivantes. – fabrizioM

2

Je suppose que je dois expliquer d'abord le problème: dans la création template_values, vous utilisez une variable d'accueil. Cette variable ne sera pas définie s'il n'y a pas d'utilisateur.

Il n'existe pas de méthode standard pour gérer cette situation. Des approches communes sont:

1. make sure that the variable is initialized in every code path (in your case: including the else case) 
2. initialize the variable to some reasonable default value at the beginning 
3. return from the function in the code paths which cannot provide a value for the variable. 

Comme Daniel, je soupçonne que, après l'appel de redirection, vous n'êtes pas censé produire une sortie, de toute façon, le code pourrait se lire

class Test(webapp.RequestHandler): 
    def get(self):  
    user = users.get_current_user() 
    if user: 
     greeting = ('Hello, ' + user.nickname()) 
    else: 
     self.redirect(users.create_login_url(self.request.uri)) 
     return 
... 

    template_values = {"greeting": greeting, 
        } 
+0

Merci. Il semblait que la deuxième option était la plus facile, donc j'ai choisi «salut = Aucun». Pourquoi le retour est-il nécessaire? – Zeynel

+1

self.redirect demandera seulement à webapp d'envoyer une redirection - c'est une fonction normale et ne peut pas vraiment abandonner l'exécution de get() (sauf quand elle déclencherait une exception). Donc, si vous ne voulez pas/ne devez pas effectuer d'autres actions après la redirection, vous devriez vraiment revenir du get tout de suite, et éviter d'effectuer plus d'activité (ce qui est soit incorrect ou inutile). –

Questions connexes