[python]mac/windows python2 多进程全局变量作用域疑问
在mac和windows上相同的python脚本,跑出了不同的效果。
就是我在main里面声明的变数,多进程执行,在windows无法访问,但mac却可以。
被卡了好久,有点困惑,这里记录一下现象~~原因不知道......
#!/usr/bin/python
#-*- coding: utf-8
def getVar(temp2):
print("temp var221 :%s"%temp2)
global temp1
print("temp var111 :%s"%temp1)
temp1 = "xiaoqiang3"
print("temp var222 :%s"%temp1)
print("temp var223 :%s"%temp2)
if __name__ == '__main__':
temp1 = "xiaoqiang"
print("temp var1 before:%s"%temp1)
getVar(temp1)
print("temp var1 after:%s"%temp1)
'''
输出如下:
temp var1 before:xiaoqiang
temp var221 :xiaoqiang
temp var111 :xiaoqiang
temp var222 :xiaoqiang3
temp var223 :xiaoqiang
temp var1 after:xiaoqiang3
'''
全局变量不需要global声明,函数内的局部变量不会因为传入的变量改变而改变
如果你需要获取并更改全局变量的值,需要在更改的地方,也就是函数内部,声明global属性,即可修改(不声明不会报错,但是打印的时候会报变量没有被引用,并且此时对象为函数内的局部变量,修改后的值无法作用到外部的全局变量)。
想看一下内存地址的变化,于是打印了一下地址:
#!/usr/bin/python
#-*- coding: utf-8
def getVar(temp2):
print("temp var2 : %s value: %s"%(id(temp2),temp2)) #140611843258912
global temp1
print("temp var21 : %s value: %s"%(id(temp1),temp1)) #140611843258912
temp1 = "xiaoqiang3"
print("temp var11 : %s value: %s"%(id(temp1),temp1)) #140611843258768
print("temp var22 : %s value: %s"%(id(temp2),temp2)) #140611843258912
temp2 = "XiaoQQ"
print("temp var33 : %s value: %s"%(id(temp2),temp2)) #140611843258816
if __name__ == '__main__':
temp1 = "xiaoqiang"
print("temp var1 before: %s value: %s"%(id(temp1),temp1)) #140611843258912
getVar(temp1)
print("temp var1 after: %s value: %s"%(id(temp1),temp1)) #140611843258768
全局变量在传参前后,内存地址不会改变,这很合理。
当全局变量被当作参数传到函数中时,这时候就是独立的存在了(局部变量),它的改变不会影响到全局变量的值和内存地址。
全局变量在得到声明修改内容后,一样不会影响到已经作为局部变量的值和内存地址,只会影响全局变量本身。
这里更改前局部变量和全局变量内存地址都是一样的,我猜测,可能python的存储是类似链表的结构,节省内存开销。
相同值的情况下,会共用指向同一个内存。只有值改变,才会申请新的内存,这很合理~(mac和windows的输出一样)
奇怪的地方
mac 多进程,可以正常打印:
#!/usr/bin/python
#-*- coding: utf-8
import multiprocessing
def fun(name):
print(test)
if __name__=="__main__":
test = "lll"
pool = multiprocessing.Pool(3)
for i in range(1,6):
st = "start {}".format(i)
pool.apply_async(func=fun,args=(st,))
pool.close()
pool.join()
而Windows 多进程打印为空,如果想要打印全局变量test,必须要在函数前声明该变量,不管怎么global声明都不行,必须要在函数前面定义
#-*- coding: utf-8
#多进程作用域,变量必须要声明到函数前面
test = "lll"
def fun(name):
print(test)
if __name__=="__main__":
# test = "lll"
pool = multiprocessing.Pool(3)
for i in range(1,6):
st = "start {}".format(i)
pool.apply_async(func=fun,args=(st,))
pool.close()
pool.join()
多线程Mac &&Windows却都可以访问全局变量
import threading
import time
def work1():
global g_num
for i in range(3):
g_num += 1
print("in work1 g_num is : %d" % g_num)
def work2():
print("in work2 g_num is : %d" % g_num)
if __name__ == '__main__':
g_num = 100
t1 = threading.Thread(target=work1)
t1.start()
time.sleep(1)
t2 = threading.Thread(target=work2)
t2.start()
'''
in work1 g_num is : 103
in work2 g_num is : 103
'''
多进程的处理,在windows那边一定要注意全局变量声明位置。
多线程没有问题。
不清楚mac和windows为什么有这个差异...先记录下来以后再来补充
Knowledge, like candlelight, can illuminate a person and countless people.