1. 程式人生 > 實用技巧 >[python]mac/windows python2 多程序全域性變數作用域疑問

[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為什麼有這個差異...先記錄下來以後再來補充