[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为什么有这个差异...先记录下来以后再来补充

原文地址:https://www.cnblogs.com/xiaoqiangink/p/14138147.html