在平時的開發(fā)中我們有時候會用到全局變量,但是很多開發(fā)語言不允許使用或者建議少使用全局變量,Python也是如此。但是有時候為了編寫程序的方便和靈活,必須使用全局變量。這篇文章記錄是我在使用Python全局變量的一些體會,寫的不是很好,歡迎大家指正!
一,使用全局變量
首先展示一段不能修改全局變量的代碼:
gl_string ="hello Python" # 定義全局變量gl_string
print(id(gl_string))# 打印全局變量gl_string的內(nèi)存地址
print(gl_string)
print("開始全局打印---------")
# 函數(shù)1
def demo1():
gl_string ="hello Objc"
print(id(gl_string))
print(gl_string)
print("demo1打印---------")
# 函數(shù)2
def demo2():
gl_string ="hello Java"
print(id(gl_string))
print(gl_string)
print("demo2打印---------")
demo1() # 調(diào)用
demo2() # 調(diào)用
# 最后打印全局變量的信息
print(id(gl_string))
print(gl_string)
print("最后全局打印---------")
打印結(jié)果如下:
4482589808
hello Python
開始全局打印---------
4482589552
hello Objc
demo1打印---------
4482512880
hello Java
demo2打印---------
4482589808
hello Python
最后全局打印---------
從打印的結(jié)果發(fā)現(xiàn),每次在函數(shù)里面給gl_string變量進(jìn)行賦值操作時,gl_string變量的內(nèi)存地址都不一樣,而且gl_string對應(yīng)的值也不一樣。從開始到結(jié)束的打印結(jié)果來看,全局變量gl_string內(nèi)存地址和對應(yīng)的值都沒有發(fā)生改變。依此可以得出這樣的結(jié)果:當(dāng)在函數(shù)里面不添加其他操作的情況下是無法修改全局變量的,函數(shù)里面的對全局變量的賦值操作實際上是系統(tǒng)幫我們創(chuàng)建了一個跟全局變量同名的局部變量
二,如何修改全局變量
還是先看一段代碼:
# 定義全局變量num
gl_string = "hello Python"
# 打印全局變量num的內(nèi)存地址
print(id(gl_string))
print(gl_string)
print("開始全局打印---------")
def demo1():
global gl_string
gl_string = "hello Objc"
print(id(gl_string))
print(gl_string)
print("demo1打印---------")
def demo2():
gl_string = "hello Java"
print(id(gl_string))
print(gl_string)
print("demo2打印---------")
demo1()
demo2()
print(id(gl_string))
print(gl_string)
print("最后全局打印---------")
上面這段代碼跟之前的那端段代碼有一點區(qū)別,現(xiàn)在的這份代碼在demo1里面添加了這句代碼global gl_string,下面看看輸出結(jié)果:
4412728496
hello Python
開始全局打印---------
4412728240
hello Objc
demo1打印---------
4412906864
hello Java
demo2打印---------
4412728240
hello Objc
最后全局打印---------
從輸出結(jié)果可以看到,demo1里面的打印結(jié)果和程序結(jié)束時打印結(jié)果是一致的,而程序開始的結(jié)果和demo2里面的結(jié)果不一樣。
我們現(xiàn)在demo2里面加一行代碼再看看輸出結(jié)果:
# 定義全局變量num
gl_string = "hello Python"
# 打印全局變量num的內(nèi)存地址
print(id(gl_string))
print(gl_string)
print("開始全局打印---------")
def demo1():
global gl_string
gl_string = "hello Objc"
print(id(gl_string))
print(gl_string)
print("demo1打印---------")
def demo2():
global gl_string
gl_string = "hello Java"
print(id(gl_string))
print(gl_string)
print("demo2打印---------")
demo1()
demo2()
print(id(gl_string))
print(gl_string)
print("最后全局打印---------")
輸出結(jié)果:
4393530544
hello Python
開始全局打印---------
4393530288
hello Objc
demo1打印---------
4393709040
hello Java
demo2打印---------
4393709040
hello Java
最后全局打印---------
從這次的輸出結(jié)果可以看出,demo2和程序結(jié)束時打印的結(jié)果是一樣的,而開始的打印結(jié)果和demo1里面的打印結(jié)果不一樣。
從以上三段代碼的打印結(jié)果最后的出如下的結(jié)論,在函數(shù)內(nèi)部使用全局變量時,如果不添加global關(guān)鍵字修飾全局變量,那么我們在函數(shù)里面對全局變量的賦值操作實際上并不是對全局變量的賦值,而是創(chuàng)建了一個跟全局變量同名的局部變量。如果用global關(guān)鍵字修飾以后的全局變量,在函數(shù)內(nèi)進(jìn)行賦值操作時確實修改了全局函數(shù)的值,但這個也只是一個假象而已,因為在每次賦值時,全局變量的內(nèi)存地址都在改變,系統(tǒng)只是將變量標(biāo)識符指向了最新的內(nèi)存地址而已,并不是在原來的內(nèi)存地址是修改。