看一个例子:
NUM = 0
ARRAY = [0]
def fun1(NUM, ARRAY):
NUM += 1
ARRAY[0] += 1
fun1(NUM, ARRAY)
print 'after fun1 %d %s' % (NUM,ARRAY)
def fun2():
global NUM
NUM += 1
ARRAY[0] += 1
fun2()
print 'after fun2 %d %s' % (NUM,ARRAY)
执行结果:
after fun1 0 [1]
after fun2 1 [2]
解释
fun1中,NUM作为int是immutable类型对象,ARRAY是list,list中的值是mutable,所以执行后全局的NUM未变但ARRAY变了;因为给immutable对象赋值,会自动创建新的局部变量来代替。
fun2中,使用Python的关键字global才可以在函数内强行操作immutable全局变量NUM,实则是重新建立了全局变量,删除了老的全局变量NUM;global是声明全局变量,nonlocal是上一层变量。但如果仅仅访问而不修改,在函数内是可以不用global直接使用的,比如在fun2中只是print NUM
判断这个引用是否可以改变源数据:
- 判断在这个局部的块中是否改变了这个变量的值,如果只是读,而没有修改操作,那么用的是全局
- 是普通类型还是引用类型,python中不必考虑这个问题,因为python都是引用类型
- 是mutable类型还是immutable类型,Java 中immutable变量是基本类型String,加了final修饰的对象等
- 其实能够修改元数据的情况只有一种就是,要修改值,是引用变量,并且是可变类型。
Python中怎么用全局变量好:
- 首先,使用基本类型的全局变量需要在每个操作它的函数、类里面用global声明还是挺麻烦的;
- 列表或元组呢,访问的时候用数字索引会降低代码的可读性;
- 用字典(dict)则可以解决上面两个问题,在简单的程序中dict应该是很合适的;
- 但是,在复杂的代码中如果需要对全局变量的修改进行一定的控制,或者在多组多个线程每组共享同类型但不同值的全局变量时,dict就无法胜任;
所以,可以自定义一个类来保存所有的全局变量:
- 简单时就直接访问成员变量;
- 需要控制时就声明为私有变量,用成员函数访问和修改;
- 多组多线程分开共享时就每组new一个新实例即可;