在平时的开发中我们有时候会用到全局变量,但是很多开发语言不允许使用或者建议少使用全局变量,Python也是如此。但是有时候为了编写程序的方便和灵活,必须使用全局变量。这篇文章记录是我在使用Python全局变量的一些体会,写的不是很好,欢迎大家指正!
一,使用全局变量
首先展示一段不能修改全局变量的代码:
gl_string ="hello Python" # 定义全局变量gl_string
print(id(gl_string))# 打印全局变量gl_string的内存地址
print(gl_string)
print("开始全局打印---------")
# 函数1
def demo1():
gl_string ="hello Objc"
print(id(gl_string))
print(gl_string)
print("demo1打印---------")
# 函数2
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("最后全局打印---------")
打印结果如下:
4482589808
hello Python
开始全局打印---------
4482589552
hello Objc
demo1打印---------
4482512880
hello Java
demo2打印---------
4482589808
hello Python
最后全局打印---------
从打印的结果发现,每次在函数里面给gl_string变量进行赋值操作时,gl_string变量的内存地址都不一样,而且gl_string对应的值也不一样。从开始到结束的打印结果来看,全局变量gl_string内存地址和对应的值都没有发生改变。依此可以得出这样的结果:当在函数里面不添加其他操作的情况下是无法修改全局变量的,函数里面的对全局变量的赋值操作实际上是系统帮我们创建了一个跟全局变量同名的局部变量
二,如何修改全局变量
还是先看一段代码:
# 定义全局变量num
gl_string = "hello Python"
# 打印全局变量num的内存地址
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("最后全局打印---------")
上面这段代码跟之前的那端段代码有一点区别,现在的这份代码在demo1里面添加了这句代码global gl_string,下面看看输出结果:
4412728496
hello Python
开始全局打印---------
4412728240
hello Objc
demo1打印---------
4412906864
hello Java
demo2打印---------
4412728240
hello Objc
最后全局打印---------
从输出结果可以看到,demo1里面的打印结果和程序结束时打印结果是一致的,而程序开始的结果和demo2里面的结果不一样。
我们现在demo2里面加一行代码再看看输出结果:
# 定义全局变量num
gl_string = "hello Python"
# 打印全局变量num的内存地址
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("最后全局打印---------")
输出结果:
4393530544
hello Python
开始全局打印---------
4393530288
hello Objc
demo1打印---------
4393709040
hello Java
demo2打印---------
4393709040
hello Java
最后全局打印---------
从这次的输出结果可以看出,demo2和程序结束时打印的结果是一样的,而开始的打印结果和demo1里面的打印结果不一样。
从以上三段代码的打印结果最后的出如下的结论,在函数内部使用全局变量时,如果不添加global关键字修饰全局变量,那么我们在函数里面对全局变量的赋值操作实际上并不是对全局变量的赋值,而是创建了一个跟全局变量同名的局部变量。如果用global关键字修饰以后的全局变量,在函数内进行赋值操作时确实修改了全局函数的值,但这个也只是一个假象而已,因为在每次赋值时,全局变量的内存地址都在改变,系统只是将变量标识符指向了最新的内存地址而已,并不是在原来的内存地址是修改。