- 在函数中定义的变量称为局部变量
- 在函数外定义的变量称为全局变量
在学习Python的时候发现变量访问有些坑,记录如下:
实验过程:
1、在函数内部访问全局变量:
g_global_var = 2017
def function1():
print(id(g_global_var))
print(id(g_global_var))
function1()
print(id(g_global_var))
结果1.png
发现在函数调用前、函数调用后以及函数内部访问全局变量,变量的地址没有发生变化。
2、以全局变量为参数,调用函数,在函数内部访问变量:
g_global_var = 2017
def function2(var):
print(id(var))
print(id(g_global_var))
function2(g_global_var)
print(id(g_global_var))
结果2.png
发现在函数调用前、函数调用后以及函数内部访问全局变量,变量的地址没有发生变化。
3、在函数内部修改全局变量:
def function3():
print(id(g_global_var))
g_global_var = 2018
print(id(g_global_var))
function3()
print(id(g_global_var))
结果3-1.png
发现程序运行会出错,提示的信息:本地变量在赋值前已经被使用,正确的做法是在使用全局变量前,用global先获取全局变量,然后就可以修改了。如果不修改全局变量(如1)可以不用global获取全局变量。
def function3():
global g_global_var
print("修改前:%d"%id(g_global_var))
g_global_var = 2018
print("修改后:%d"%id(g_global_var))
print("访问前:%d"%id(g_global_var))
function3()
print("访问后:%d"%id(g_global_var))
结果3-2.png
从输出结果可以发现,修改后全局变量的地址发生了改变,而且函数调用后,函数外部的全局变量的地址也随之发生了变化,也就是说,这种方式可以修改全局变量。
4、以全局变量为参数,调用函数,在函数内部修改变量:
def function4(var):
print("修改前:%d"%id(var))
var = 2018
print("修改后:%d"%id(var))
print("访问前:%d(%d)"%(g_global_var, id(g_global_var)))
function4(g_global_var)
print("访问后:%d(%d)"%(g_global_var, id(g_global_var)))
结果4.png
从输出结果可以发现,修改后变量的地址发生了改变,但函数调用结束后,全局变量的地址没有发生变化,也就是说,这种方式不能修改全局变量。
5、在函数内部修改变量,查看变量修改前后情况:
def function5():
var = 2017
print("修改前:%d(%d)"%(var,id(var)))
var = 2018
print("修改后:%d(%d)"%(var,id(var)))
function5()
结果5.png从输出结果可以发现,修改前后局部变量的地址发生了变化。
6、在函数内部修改容器变量,查看变量修改前后情况:
def function6():
var = [2007]
print("修改前:%s(%d)"%(var,id(var)))
var.append(2008)
print("修改后:%s(%d)"%(var,id(var)))
function6()
结果6.png
从输出结果可以发现,修改前后,列表内容发生了变化,但地址没有发生变化。同理验证全局容器,发现地址也没有变化。
实验结论:
-
在Python中,赋值操作是会改变变量地址的。
-
在Python中,类似append操作,是不会改变容器变量地址的。
-
如果函数内部没有改改全局变量地址的操作,可以直接访问全局变量,不用在访问前加global。
-
如果函数内部有修改全局变量地址的操作,不可以直接访问全局变量,需要在访问前加global。
-
在Python中,函数传参是引用传参。尽管是引用传参,但如果函数内部有修改了变量的地址的操作,如赋值操作,则外部变量的内容也不会发生变化。
以上代码可以在GitHub找到。
网友评论