疑問
- 為什么main中不能寫global x語句?
- 在函數中如何修改global變量?
- 在main中修改了global變量后,在子進程中為什么沒有效果?
- 如何利用進程池的initializer參數(函數)修改子進程中的global變量?
代碼如下:
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 # @Time : 2018/9/1 8:21 4 # @Author : dswang 5 6 from multiprocessing import Pool, current_process 7 8 VAR0 = 'module' 9 10 11 def f0(change=False): 12 print 'in func f0, pid:{}'.format(current_process().pid) 13 # time.sleep(2) 14 if change: 15 global VAR0 16 VAR0 = 'f0' 17 print VAR0 18 19 20 def ps_init(): 21 global_dct = globals() 22 print "global_dct.keys():", global_dct.keys() 23 print 'VAR0 in global:', global_dct.get('VAR0') 24 global VAR0 25 VAR0 = 'ps' 26 print 'VAR0 in global:', global_dct.get('VAR0') 27 28 29 if __name__ == '__main__': 30 VAR0 = 'main' 31 pool = Pool(processes=1, initializer=ps_init) 32 pool.apply(func=f0, args=()) 33 34 f0() 35 f0(True) 36 print 'in main, pid:{}'.format(current_process().pid) 37 print 'VAR0 in main:' 38 print VAR0 39 40 print 'the end'
結果為:
1 global_dct.keys(): ['f0', 'VAR0', '__builtins__', '__file__', '__package__', 'current_process', '__name__', '__doc__', 'Pool', 'ps_init'] 2 VAR0 in global: module 3 VAR0 in global: ps 4 in func f0, pid:6504 5 ps 6 in func f0, pid:6216 7 main 8 in func f0, pid:6216 9 f0 10 in main, pid:6216 11 VAR0 in main: 12 f0 13 the end
解疑
1、為什么main中不能寫global x語句?
因為 if __name__ == '__main__': 語句並不開辟新的作用域,所以main中的變量VAR0已經是在全局作用域,
再寫關鍵字global是多余的,會報錯:
SyntaxWarning: name 'VAR0' is assigned to before global declaration global VAR0.
2、在函數中如何修改global變量?
在函數中修改global變量,需要先聲明變量為global,如代碼16和24行中,在函數f0中的“global VAR0”語句。
3、在main中修改了global變量后,在子進程中為什么沒有效果?
注:6216是主進程,6504是子進程。
從運行結果中看到(結果第2行):子進程中的VAR0並沒有因為main中的修改而改變,
依然保持module中的值“module”。當子進程中修改后,VAR0變成了“ps”,在隨后f0函數中依然是"ps"。
然后,回到main中(代碼34行),VAR0為main中修改后的“main”。最后,main中函數f0對VAR0再次修改為“f0”,
因此,VAR0在f0和main中都變成了“f0”,見結果第9和第12行。
4、如何利用進程池的initializer參數(函數)修改子進程中的global變量?
參考代碼和問題3的回答。
總結
- if語句不開辟新的作用域,因此不能在main中寫global關鍵字,直接修改即可;
- 函數中要修改全局變量,需要先聲明為全局變量:global x;
- 子進程中的全局變量取module中的值,main中修改module的全局變量不影響子進程。