Por qué algunas variables de Python se mantienen globales, mientras que otras requieren una definición como global

Me cuesta un poco entender por qué algunas variables son locales y otras globales. Por ejemplo, cuando bash esto:

from random import randint score = 0 choice_index_map = {"a": 0, "b": 1, "c": 2, "d": 3} questions = [ "What is the answer for this sample question?", "Answers where 1 is a, 2 is b, etc.", "Another sample question; answer is d." ] choices = [ ["a) choice 1", "b) choice 2", "c) choice 3", "d) choice 4"], ["a) choice 1", "b) choice 2", "c) choice 3", "d) choice 4"], ["a) choice 1", "b) choice 2", "c) choice 3", "d) choice 4"] ] answers = [ "a", "b", "d" ] assert len(questions) == len(choices), "You haven't properly set up your question-choices." assert len(questions) == len(answers), "You haven't properly set up your question-answers." def askQ(): # global score # while score  ") if response == answers[question]: score += 1 print "That's correct, the answer is %s." % choices[question][choice_index_map[response]] # eg choices[1][2] else: score -= 1 print "No, I'm sorry -- the answer is %s." % choices[question][choice_index_map[answers[question]]] print score askQ() 

Me sale este error:

 Macintosh-346:gameAttempt Prasanna$ python qex.py Answers where 1 is a, 2 is b, etc. a) choice 1 b) choice 2 c) choice 3 d) choice 4 > b Traceback (most recent call last): File "qex.py", line 47, in  askQ() File "qex.py", line 39, in askQ score += 1 UnboundLocalError: local variable 'score' referenced before assignment 

Ahora, tiene sentido para mí por qué me está arrojando un error en la puntuación. No lo configuré globalmente (comenté esa parte intencionalmente para mostrar esto). Y específicamente no estoy usando la cláusula while para que siga adelante (de lo contrario, ni siquiera ingresará a la cláusula). Lo que me confunde es por qué no me da el mismo error para las preguntas, las opciones y las respuestas. Cuando elimino esas dos líneas, el script funciona perfectamente bien, incluso sin que yo defina preguntas, respuestas y elecciones como variables globales. ¿Porqué es eso? Esto es lo único que no he podido descubrir en otras preguntas: aquí parece que Python está siendo inconsistente. ¿Tiene que ver conmigo usando listas como las otras variables? ¿Porqué es eso?

(Además, póster por primera vez; muchas gracias por toda la ayuda que he descubierto y no necesito hacer preguntas).

Es porque estás asignando a la score . Las variables de questions y answers solo se leen, no se escriben.

Cuando asigna una variable, ese nombre tiene el scope del método, clase, etc. actual en el que se encuentra. Cuando intenta obtener el valor de una variable, primero intenta el scope actual y luego los ámbitos externos, hasta que encuentra una coincidencia.

Esto tiene sentido si crees que lo global es una directiva de analizador

Cuando estas haciendo

 score += 1 

se traduce a

 score = score + 1 

cuando el analizador llega a ‘score =’ hace que el intérprete no busque fuera del espacio local.

http://docs.python.org/2/reference/simple_stmts.html#global

Lo que sucede es que Python verificará sus variables en el ámbito local antes de verificar el scope global. Por lo tanto, cuando se trata de questions y answers , nunca se configuran en el ámbito local, por lo que Python se traslada al ámbito global, donde se encuentran. Pero para la score , Python ve que haces una tarea ( score += 1 o score -= 1 ) y se ajusta al scope local. Pero cuando menciona la score en estas declaraciones, aún no existe, por lo que Python lanza una excepción.