讨论下python中全局变量的使用

首先看一段代码:多线程

A = 0
B = [0]

def fun1(A, B):
    A += 1
    B[0] += 1
fun1(A, B)
print 'after fun1 %d %s' % (A,B)

def fun2():
    global A
    A += 1
    B[0] += 1
fun2()
print 'after fun2 %d %s' % (A,B)

执行后的结果:app

after fun1 0 [1]
after fun2 1 [2]

fun1中,A做为基本类型(int)是值传递,B不是基本类型(list)则是引用传递,因此执行后全局的A未变但B变了;函数

(若是熟悉C++就很容易理解,相似的概念:指针、引用、深拷贝、浅拷贝等)spa

注意,与C++不一样,Python中字符串str为基本类型线程

fun2中,使用Python的关键字global才能够在函数内操做全局变量A,但B不须要global却能直接使用,这样能够避免一些“自觉得是”的逻辑错误;指针

(注意,若是仅仅访问而不修改,在函数内是能够不用global直接使用的,好比在fun2中只是print A)code

 

有了上面的理解后,咱们来分析下在Python中怎么用全局变量好:blog

首先,使用基本类型的全局变量须要在每一个操做它的函数、类里面用global声明仍是挺麻烦的;索引

列表或元组呢,访问的时候用数字索引会下降代码的可读性;字符串

用字典(dict)则能够解决上面两个问题,在简单的程序中dict应该是很合适的;

可是,在复杂的代码中若是须要对全局变量的修改进行必定的控制,或者在多组多个线程每组共享同类型但不一样值的全局变量时,dict就没法胜任;

综上,我的认为自定义一个类来保存全部的全局变量是最好的方法:

  简单时就直接访问成员变量;

  须要控制时就声明为私有变量,用成员函数访问和修改;

  多组多线程分开共享时就每组new一个新实例便可;

示例一:

#common.py
class MyGlobal:
    def __init__(self):
        self.A = 0
        self.B = [0]
GL = MyGlobal()

#main.py
from common import *
def fun():
    GL.A += 1
    GL.B[0] += 1
fun()
print 'after fun %d %s' % (GL.A,GL.B) #执行./main.py after fun 1 [1]

示例二:

#common.py
import threading
class MyGlobal:
    def __init__(self, i, setname):
        self.setname = setname
        self.A = i
        self.B = [i]

#main.py
from common import *
def fun_trd(gl):
    print '%s %d %s' % (gl.setname,gl.A,gl.B)
#两组,每组三个线程
trds = []
for i in range(0,2):
    setname = 'SET%d' % i
    gl = MyGlobal(i, setname)
    for k in range(0,3):
        t = threading.Thread(target=fun_trd, args=(gl,))
        t.setDaemon(True)
        t.start()
        trds.append(t)
for t in trds:
    t.join()

#执行./main.py
SET0 0 [0]
SET0 0 [0]
SET0 0 [0]
SET1 1 [1]
SET1 1 [1]
SET1 1 [1]

over

相关文章
相关标签/搜索