python解释器查找变量时遵循‘legb’原则即:1.先在local即局部作用域中查找变量声明和值,如果没有找到;2则在函数的closure属性中查找变量(只有闭包函数要考虑)即enclosing,如果还没有找到;3则在全局作用域(global)中查找变量,如果还是没有找到;4则在built-in的变量中查找,也就是python的关键字和默认的全局函数(e.g. list tuple open print)。
  举个例子说明一下:

age = 18
def happy_birthday():
    print("age {}, happy birthday ~".format(age))
happy_birthday()
print("your age is {}".format(age))
'''
age 18, happy birthday ~
your age is 18
'''

  分析一下代码,当调用happy_birthday()函数时,python对其内部变量age的查找过程是:1.在函数内局部查找发现没有变量age被定义,接下就去找嵌套函数,发现这个函数内没有嵌套函数,然后到全局范围去找,发现在函数外部age被定义了所以这个函数用了全局变量age=18的值,变量age已经找到,结束查找过程。然后我们来看下面一段代码:

age = 18
def happy_birthday():
    print("age {}, happy birthday ~".format(age))
    age += 1 # 修改处
happy_birthday()
print("your age is {}".format(age))
'''
Traceback (most recent call last):
  File "D:\Sublime Text 3\ts.py", line 5, in <module>
    happy_birthday()
  File "D:\Sublime Text 3\ts.py", line 3, in happy_birthday
    print("age {}, happy birthday ~".format(age))
UnboundLocalError: local variable 'age' referenced before assignment
'''

  我在happy_birthday函数后面加了一句age+=1,我试图去修改age的值,但是python解释器报错了。错误是age没被定义。why?age明明是个全局变量被定义了。原因是python中的全局变量不仅仅是可以直接定义在函数外部还可以用global关键字在函数内部声明变量为全局变量。这两种方式它们的不同点在于:第一种方式,它的值在函数内部只能被引用不可被更改(这就是报错的原因,在这点上python不同于其他语言),要想更改只能再函数外更改即以全局的方式修改或者使用第二种方式。第二种方式,你在函数内部以global关键字声明该变量,因为这个变量在函数内部所以它可以在函数内部被修改,又因为它被定义为global,所以它又是全局的,它的最终值可以在函数外被访问到当然也可以被修改。所以,改一下代码就是:

age = 18
def happy_birthday():
    global age
    print("age {}, happy birthday ~".format(age))
    age += 1
happy_birthday()
print("your age is {}".format(age))
'''
age 18, happy birthday ~
your age is 19
'''

  总结:当你想保留局部作用域(如函数)中的变量,那么你应当用global关键字对该变量进行声明,然后再定义这个变量,当退出局部作用域后这个变量仍然存在。当你想把全局变量用到局部区间并不仅仅是访问的话(例如想修改它),那么你应当在局部作用域中对该全局变量用global进行声明,也就是对于全局变量要把它拿到函数中使用时应当用global进行声明。从这儿也可以发现global关键字一般都是用在局部作用域中(例如函数中),而不是用在全局中(函数外部),当然你也可以用不过是多次一举。