- 以下面的例子为例:
total = 0 # total是一个全局变量
def plus(arg1, arg2):
total = arg1 + arg2 # total在这里是局部变量
print("函数内部的局部变量total=", total)
print("函数内部的局部变量total的内存地址是:", id(total))
return total
plus(10, 20)
print("函数外部的全局变量total=",total)
print("函数外部的全局变量toal的内存地址是:", id(total))
- 很明显,函数plus内部通过total = arg1 + arg2语句,新建了一个局部变量total,它和外面的全局变量total是两码事。但是如果我们想要在函数内部修改外面的全局变量total,则使用global关键字!global:指定当前变量使用外部的全局变量。
total = 0 # total是一个全局变量
def plus(arg1, arg2):
global total # 使用global关键字申明此处的total引用外部的total
total = arg1 + arg2 # total在这里是局部变量
print("函数内部的局部变量total=", total)
print("函数内部的局部变量total的内存地址是:", id(total))
return total
plus(10, 20)
print("函数外部的全局变量total=",total)
print("函数外部的全局变量toal的内存地址是:", id(total))
- 再看下面的例子:
a = 1 # 全局变量
print("函数outer调用之前全局变量a的内存地址: ", id(a))
def outer():
a = 2 # 闭包外部的变量a
print("函数outer调用之时闭包外部的变量a的内存地址: ", id(a))
def inner():
a = 3 # 闭包内部的变量a
print("函数inner调用之后闭包内部变量a的内存地址: ", id(a))
inner()
print("函数inner调用之后,闭包外部的变量a的内存地址: ", id(a))
outer()
print("函数outer执行完毕,全局变量a的内存地址: ", id(a))
- 如果inner内部想使用outer里面的那个a,而不是全局变量的那个a,怎么办?用global关键字?先试试看吧:
a = 1 # 全局变量
print("函数outer调用之前全局变量a的内存地址: ", id(a))
def outer():
a = 2 # 闭包外部的变量a
print("函数outer调用之时闭包外部的变量a的内存地址: ", id(a))
def inner():
global a # 注意这行
a = 3 # 闭包内部的变量a
print("函数inner调用之后闭包内部变量a的内存地址: ", id(a))
inner()
print("函数inner调用之后,闭包外部的变量a的内存地址: ", id(a))
outer()
print("函数outer执行完毕,全局变量a的内存地址: ", id(a))
- 上面的代码段,很明显,global使用的是全局变量a。解决方法:使用nonlocal关键字!它可以修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量。将global a改成nonlocal a,可以看到我们真的引用了outer函数中的闭包外部的变量a。
a = 1 # 全局变量
print("函数outer调用之前全局变量a的内存地址: ", id(a))
def outer():
a = 2 # 闭包外部的变量a
print("函数outer调用之时闭包外部的变量a的内存地址: ", id(a))
def inner():
nonlocal a # 注意这行!!! 引用了闭包外部的变量a
a = 3 # 闭包内部的变量a
print("函数inner调用之后闭包内部变量a的内存地址: ", id(a))
inner()
print("函数inner调用之后,闭包外部的变量a的内存地址: ", id(a))
outer()
print("函数outer执行完毕,全局变量a的内存地址: ", id(a))