global 关键字
上面提到在函数内部去修改全局变量的时候,会创建一个和全局变量名字一样的局部变量,真正的全局变量的值没有发生变化,这其实是python使用屏蔽的方式保护了全局变量。
但如果真的需要函数试图去修改全局变量,可以使用global关键字达到目的,例如:
>>> count = 5
>>> def fun():
global count
count = 10
print(count)
>>> fun()
10
>>> count
10
内嵌函数
允许在函数内创建另外一个函数,成为内嵌函数或内部函数,内部函数整个作用域在外部函数之内。
注意:内部函数只能在外部函数体中被随意调用,出了这个函数体,就没有任何函数可以对内部函数进行调用,不然就会报错。
闭包 closure
闭包是函数式编程的一个重要的语法结构。
python的闭包从表现形式上定义为:如果在一个内部函数里,在对外部作用域的变量进行引用,那么内部函数就被认为是闭包。
>>> def funX(x):
def funY(y):
return x*y
return funY
>>> i = funX(8)
>>> i(5)
40
>>>
在一个内部函数里对外部作用域的变量进行引用,比如上述X就是被引用的变量,x在外部作用域funX函数里面,但不再全局作用域内,则这个内部函数funY是一个闭包。
在闭包中,外部函数的局部变量对应内部函数的局部变量,事实上相当于之前说的全局变量跟局部变量的关系,在内部函数中,只能对外部函数的局部变量进行访问,不能进行修改。
>>> def funX():
x = 5
def funY():
x *= x
return x
return funY
>>> funX()()
Traceback (most recent call last):
File "<pyshell#22>", line 1, in <module>
funX()()
File "<pyshell#21>", line 4, in funY
x *= x
UnboundLocalError: local variable 'x' referenced before assignment
这个报错与之前说全局变量的时候一样,python认为内部函数的x是局部变量,外部函数的x就被屏蔽起来,所以执行x *= x的时候,右边根本找不到局部变量x的值,因此报错
在python3以前,只能间接通过容器类型来存放,因为容器类型不是放在栈里,所以不会被屏蔽掉
>>> def funX():
x = 5
def funY():
x[0] *= x[0]
return x[0]
return funY
>>> funX()()
25
在python3中,使用关键字nonlocal,使用方法与global一致
>>> def funX():
x = 5
def funY():
nonlocal x
x *= x
return x
return funY
>>> funX()()
25
课后题
1.如果希望在函数中修改全局变量的值,应该使用什么关键字?
2.在嵌套的函数中,如果希望在内部函数修改外部函数的局部变量,使用什么关键字?
3.python的函数可以嵌套,但是注意访问的作用域问题,请问以下代码存在什么问题?
def outside():
print('I am outside!')
def inside():
print('I am inside!')
inside()
4.为何代码A没有报错,代码B报错了呢?应该如何修改?
代码 A——
def outside():
var = 5
def inside():
var = 3
print(var)
inside()
outside()
代码B——
def outside():
var = 5
def inside():
print(var)
var = 3
inside()
outside()
5.请问如何访问funIn()呢?
def funOut():
def funIn():
print('宾果!你成功访问到我啦!')
return funIn()
6.以下是闭包的一个例子,请你目测下会打印什么内容?
def funX():
x = 5
def funY():
nonlocal x
x += 1
return x
return funY
a = funX()
print(a())
print(a())
print(a())
解:
1.global关键字
2.nonlocal关键字
3.使用嵌套函数要注意一点就是作用域问题,inside() 函数是内嵌在 outside() 函数中的,别的函数体里是无法对其进行调用的
4.这里 outside() 函数里有一个 var 变量,但要注意的是,内嵌函数 inside() 也有一个同名的变量,Python 为了保护变量的作用域,故将 outside() 的 var 变量屏蔽起来,因此此时是无法访问到外层的 var 变量的。
5.只需要直接调用 funOut() 即可:
funOut()
宾果!你成功访问到我啦!
6.6 7 8
来源:CSDN
作者:half ~summer
链接:https://blog.csdn.net/qinshangwy/article/details/104022990