- 函数作用域
a = 1
print("函数outer调用之前全局变量a的内存地址: ", a , id(a))
def outer():
a = 2
print("函数outer调用之时闭包外部的变量a的内存地址: ", a, id(a))
def inner():
a = 3
print("函数inner调用之时闭包内部变量a的内存地址: ", a, id(a))
inner()
print("函数inner调用之后闭包外部的变量a的内存地址: ", a, id(a))
outer()
print("函数outer执行完毕,全局变量a的内存地址: ", a, id(a))
函数outer调用之前全局变量a的内存地址: 1 140704120484688
函数outer调用之时闭包外部的变量a的内存地址: 2 140704120484720
函数inner调用之时闭包内部变量a的内存地址: 3 140704120484752
函数inner调用之后闭包外部的变量a的内存地址: 2 140704120484720
函数outer执行完毕,全局变量a的内存地址: 1 140704120484688
- global 关键字
a = 1
print("函数outer调用之前全局变量a的内存地址: ",a , id(a))
def outer():
a = 2
print("函数outer调用之时闭包外部的变量a的内存地址: ", a, id(a))
def inner():
global a #这里更改了!!!
a = 3
print("函数inner调用之时闭包内部变量a的内存地址: ", a, id(a))
inner()
print("函数inner调用之后闭包外部的变量a的内存地址: ", a, id(a))
outer()
print("函数outer执行完毕,全局变量a的内存地址: ", a, id(a))
函数outer调用之前全局变量a的内存地址: 1 140704120484688
函数outer调用之时闭包外部的变量a的内存地址: 2 140704120484720
函数inner调用之时闭包内部变量a的内存地址: 3 140704120484752
函数inner调用之后闭包外部的变量a的内存地址: 2 140704120484720
函数outer执行完毕,全局变量a的内存地址: 3 140704120484752
把inner函数内的a声明为global后,更改的是最外层的a,最外层a原来为1,更改后为3。
- nonlocal 关键字
a = 1
print("函数outer调用之前全局变量a的内存地址: ",a , id(a))
def outer():
a = 2
print("函数outer调用之时闭包外部的变量a的内存地址: ", a, id(a))
def inner():
nonlocal a #这里又更改了
a = 3
print("函数inner调用之时闭包内部变量a的内存地址: ", a, id(a))
inner()
print("函数inner调用之后闭包外部的变量a的内存地址: ", a, id(a))
outer()
print("函数outer执行完毕,全局变量a的内存地址: ", a, id(a))
函数outer调用之前全局变量a的内存地址: 1 140704120484688
函数outer调用之时闭包外部的变量a的内存地址: 2 140704120484720
函数inner调用之时闭包内部变量a的内存地址: 3 140704120484752
函数inner调用之后闭包外部的变量a的内存地址: 3 140704120484752
函数outer执行完毕,全局变量a的内存地址: 1 140704120484688
nonlocal 关键字使inner函数中的a变为outer函数中的a,更改的是外边一层的a。
- 例题
a = 10
def test():
a += 1
print(a)
test()
结果: error
Python的规则是,如果在函数内部要修改一个变量,那么这个变量需要是内部变量,除非你用global声明了它是外部变量。很明显,我们没有在函数内部定义变量a,所以会弹出局部变量在未定义之前就引用的错误。
name ='jack'
def f1():
print(name)
def f2():
name = 'eric'
f1()
f2()
结果: jack
f2中调用f1,我们要从f1的定义处寻找最近的name定义,是外部的jack。
Python函数的作用域取决于其函数代码块在整体代码中的位置,而不是调用时机的位置。
name = 'jack'
def f2():
name = 'eric'
return f1
def f1():
print(name)
ret = f2()
ret()
结果:还是jack!!