Python中有一种变量是全局共享的,这种变量就是全局变量。
一个类中,或是一个进程里,这种变量是怎么玩的呢?局部想要修改全局,是不是一定要global呢?
答案是:不一定。
全局变量怎么改
为什么敢这么豪横地说,上代码。
num = 10
nums = [10, 20]
def func1():
global num
num += 10
def func2():
nums.append(30)
print(num)
func1()
print(num)
print("-------------------")
print(nums)
func2()
执行之后的结果是

显然,全局变量nums并没有在func2中设置global,但是依然被修改了。
所以我们得出结论:
可变类型的全局变量,局部修改不要global;
不可变类型全局变量,局部修改需要修改,需要加global。(str,tuple,数字)
但是。。。
如果直接修改nums = [1, 2],这样的话也是需要global的。
这方面的原因可参考之前的一篇笔记《python之从内存读写的角度,学习玩转list》。
线程中全局变量怎么玩
定义了一个全局变量,一个局部修改了它,在别的地方进行访问的时候,会是什么样的情形呢?
先说结论:全局变量在局部的线程调用中修改,在其他地方调用这个全局变量的线程访问的是修改后的值。
#!/usr/bin/env python
import threading
import time
num = 10
def func1():
global num
num += 1
print("func1中num值是:%d" % num)
def func2():
print("func2中num值是:%d" % num)
if __name__ == '__main__':
t1 = threading.Thread(target=func1)
t2 = threading.Thread(target=func1)
t1.start()
time.sleep(0.1)
t2.start()
time.sleep(0.1)
print("main中num值是:%d" % num)
可以看出线程2函数访问的是线程1处理之后的全局变量。

多线程共享全局变量为args参数
当线程函数的参数是以线程的args参数传入的方式时?线程之间对全局变量的访问还正常吗?
#!/usr/bin/env python
import threading
import time
def func1(para):
para.append(30)
print("func1修改后nums值是:%s" % str(para))
def func2(para):
print("func2修改后nums值是:%s" % str(para))
nums = [10, 20]
if __name__ == '__main__':
t1 = threading.Thread(target=func1, args=(nums,))
t2 = threading.Thread(target=func1, args=(nums,))
t1.start()
time.sleep(0.1)
t2.start()
time.sleep(0.1)
print("main中num值是:%s" % str(nums))
线程2访问的全局变量依然是线程1修改后的,即多线程共享全局变量。

之所以 多线程 需要共享全局变量,是因为多任务是配合使用的。
比如说:一个函数是下载图片,一个函数是处理这些图片,一个函数是发送这些图片。这样的话,如果下载的图片和处理方法之间操作的图片不共享的话,必须要等上一步操作结束,下一流程才能介入,这就不是多任务的并发了,而是单任务的依次执行了。
至于多线程共享全局变量的问题,下回分解。