2012-11-13 31 views
4

我有一点麻烦理解为什么有些变量是局部的,有些是全球性的。例如。当我试试这个:为什么一些Python变量停留全球性的,而有些需要定义全球

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 < 3: 
     question = randint(0, len(questions) - 1) 

     print questions[question] 
     for i in xrange(0, 4): 
      print choices[question][i] 
     response = raw_input("> ") 

     if response == answers[question]: 
      score += 1 
      print "That's correct, the answer is %s." % choices[question][choice_index_map[response]] 
      # e.g. 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() 

我得到这个错误:

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 <module> 
    askQ() 
    File "qex.py", line 39, in askQ 
    score += 1 
UnboundLocalError: local variable 'score' referenced before assignment 

现在,它完全是有道理的我,为什么它抛出我一个错误的分数。我没有在全球范围内设置它(我有意将这部分内容表明出来)。而且我特别不使用while子句来让它继续前进(否则它甚至不会输入该子句)。令我困惑的是为什么它不会给我提出同样的问题,选择和答案。 当我取消注释这两行时,脚本完美无缺 - 即使没有我将问题,答案和选项定义为全局变量。这是为什么?这是我无法从搜索其他问题中发现的一件事 - 在这里,Python似乎并不一致。它是否与我使用列表作为其他变量?这是为什么?

(另外,第一次海报,非常感谢所有我发现虽然有帮助,不需要发问。)

+2

分配的方法*总是*创建一个[新]本地绑定,除非该变量是'global''ed:转让不会使变量“非全局”,而是与阴影一个新的绑定全局变量。 – 2012-11-13 03:10:32

回答

4

这是因为你分配给scorequestionsanswers只能被读取,不能写入。

当您分配给变量时,该名称具有您所在的当前方法,类等的范围。当您尝试获取变量的值时,它首先尝试当前范围,然后外部范围,直到找到匹配。

+0

这太好了。感谢您的回应!完全合理。 – pswaminathan

2

这非常有意义,如果你认为全球是一个解析器指令

当你在做

​​3210

被翻译成

score = score + 1 

当解析器到达“得分='它会导致解释器不在本地空间之外进行搜索。

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

+0

这确实有道理。我曾经想过,当一个变量被定义在一个高于我所使用的变量的块中时,该变量上的所有操作都被保留在其范围内。尽管如此,感谢您链接这一点。这有助于我的理解,即分配遵循与阅读不同的过程。 – pswaminathan

1

会发生什么事是,Python会在局部范围内检查您的变量它会检查全局范围之前。所以,当谈到questionsanswers,它们永远不会在局部范围内设置,所以Python就移动到全球范围内,在那里他们被发现。但对于score,Python看到你在做对本地范围的分配(score += 1score -= 1)和锁。但是当你在这些语句中提到score时,它还不存在,所以Python会引发异常。

+0

这太好了。感谢您的回应!完全合理。 – pswaminathan