[python]mac/windows python2 多程序全域性變數作用域疑問
阿新 • • 發佈:2020-12-15
在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為什麼有這個差異...先記錄下來以後再來補充