小甲鱼Python3学习笔记之第二十讲(仅记录学习)

第二十讲:内嵌函数和闭包

一、知识点:

0.global关键字:内部作用域想要对外部作用域的变量进行修改时需要用到。例如:

>>> num = 1
>>> def myfun():
	global num
	print(num)
	num = 2
	print(num)
结果:>>> myfun()
1
2

1.内嵌函数:内部函数作用域在外部函数作用域之内,且只能在外部函数内调用内部函数。例如:

>>> def fun1():
	print('第一个函数')
	def fun2():
		print('内嵌函数')
	fun2()

	
结果:>>> fun1()
第一个函数
内嵌函数
>>> fun2()
Traceback (most recent call last):
  File "<pyshell#15>", line 1, in <module>
    fun2()
NameError: name 'fun2' is not defined

2.闭包:内部函数对外部函数作用域里变量的引用(非全局变量),则称内部函数为闭包。例如:

>>> def test(num):
	def test_in(num_in):
		print('在test_in函数,num_in is %d'%num_in)
		return num+num_in
	return test_in

结果:>>> i = test(20)
>>> print(i(100))
在test_in函数,num_in is 100
120

闭包思考:

①闭包似优化了变量,原来需要类对象完成 的工作,闭包也可以完成。

②由于闭包引用了外部函数的局部变量,则外部函数的变量没有及时释放,消耗内存。

3.nonlocal关键字:可以在嵌套函数中修改嵌套作用域中的变量。例如:

>>> def func():
	i = 1
	def func1():
		nonlocal i
		i = 2
	func1()
	print(i)

	
结果:>>> func()
2
----------------------------------------------------我是一条分割线------------------------------------------------------

二、课后作业:

0.如果希望在函数中修改全局变量的值,应该使用什么关键字?

global

1.在嵌套的函数中,如果希望在内部函数修改外部函数的局部变量,应该使用什么关键字?

nonlocal

2.Python函数可以嵌套,但要注意访问的作用域问题哦,请问以下代码存在什么问题?

>>> def outside():
	print('I am outside!')
	def inside():
		print('I am inside!')
>>> inside()

inside()是内部函数,不能在外部调用。使用嵌套函数需要注意的一点就是作用域问题。

3.请问为什么代码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()

代码B中外部函数有一个VAR变量,嵌套函数也有一个同名的VAR变量,python为了保护变量的作用域,会将外部函数的VAR变量屏蔽,因此嵌套函数无法访问到外部函数的VAR变量。如果要修改,可以使用nonlocal关键字。

4.请问如何访问funIn函数呢?

>>> def funOut():
	def funIn():
		print('宾果!你成功访问到我啦!')
	return funIn()
答案:>>> funOut()
宾果!你成功访问到我啦!

5.请问如何访问funIn函数呢?

>>> def funOut():
	def funIn():
		print('宾果!你成功访问到我啦!')
	return funIn
>>> funOut()()
宾果!你成功访问到我啦!

6.以下是“闭包”的一个例子,请你目测下会打印什么内容?

>>> def funX():
	x = 5
	def funY():
		nonlocal x
		x += 1
		return x
	return funY

>>> a = funX()
>>> print(a())
>>> print(a())
>>> print(a())

6

7

8

当a=funX()的时候,只要a变量没有被重新赋值,funX()就没有被释放,也就是说局部变量x没有被重新初始化。所以说当全局变量不适用的时候,可以考虑使用闭包更安全稳定。

----------------------------------------------------我是一条分割线------------------------------------------------------

猜你喜欢

转载自blog.csdn.net/huashu2017/article/details/80915037