之前寫函數的時候,由於傳參實在太多,於是將某個數組定義爲全局變量,在函數中直接使用。
可是在使用過程中發現會報錯,原因是在另一個調用函數中,該全局變量的類型被修改了,那這邊正好徹底用幾個例子來理清一下python中global關鍵字可以起到的作用。
案例一:
先說我碰到的問題(並沒有貼上源代碼,下面的例子是自己抽象出一個方便大家理解的小case)程序大概就是這樣
#error case
param = 10
def test():
if (param == 10):
print("equal 10")
else:
print("not equal 10")
def main():
global param
param = "hello world"
test()
if __name__ == "__main__":
main()
結果這個程序的輸出並不符合我一開始的預期,我預期是輸出 “equal 10”,但結果是 “not equal 10”
接下來就分析原因。
因爲在 main() 函數中,param 先被當做全局引用,並修改了他的類型,從 int 型變成了 str 型,因此在後面調用 test() 函數的時候,判定 param==10 結果爲false。
即使把 test() 函數放到以下位置,也不會改變輸出結果。
#error case
param = 10
def test():
if (param == 10):
print("equal 10")
else:
print("not equal 10")
def main():
global param
param = "hello world"
if __name__ == "__main__":
main()
test()
正確的做法,應該只能通過傳參,並且對於全局變量不要隨意修改。反正 PYTHON 在函數外定義的變量均當做全局變量來處理,也不需要畫蛇添足加上 global 關鍵字。只有當確認需要對 global 變量做出修改的時候,再使用 global 關鍵字!
案例二:
接下來通過其他的 global 的例子,進一步加深理解。
PYTHON 變量默認是全局變量,在不申明 global param 的情況下,即下例,程序可以正確輸出
“param_value:10 param_id:140704526292288”。
param = 10
def main():
print("param_value:%d\t param_id:%d" %(param, id(param)))
if __name__ == "__main__":
main()
接下來測試當 param 被 global 申明,結果就有些不一樣。
#error case
param = 10
def main():
print("param_value:%d\t param_id:%d" %(param, id(param)))
global param
param = 6
print("param_value:%d\t param_id:%d" %(param, id(param)))
if __name__ == "__main__":
main()
依然是申明瞭變量,但是在 global 之前獲取了 param 的值和 id。
這種情況下,程序會報 syntax error,理由是 “name 'param' is used prior to global declaration”,即變量在定義之前就被使用。而只要變量在這個函數塊內被申明,他的作用域就是整個函數,如果在申明之前被引用,那就會報錯。
用這個例子應該能比較清楚的說明 global 的用法。
param = 10
def test():
print("param_value:%d\t param_id:%d" %(param, id(param)))
if (param == 10):
print("equal 10")
else:
print("not equal 10")
def main():
global param
print("param_value:%d\t param_id:%d" %(param, id(param)))
param = 6
print("param_value:%d\t param_id:%d" %(param, id(param)))
test()
if __name__ == "__main__":
print("param_value:%d\t param_id:%d" %(param, id(param)))
main()
輸出結果爲
param_value:10 param_id:140704526292288
param_value:10 param_id:140704526292288
param_value:6 param_id:140704526292160
param_value:6 param_id:140704526292160
not equal 10