Python 闭包及装饰器的理解

1.闭包定义
------------------- 内部函数对外部函数作用域里变量的引用
先来看一个例子,这个例子之前看到过,自己测试了下

#-*-coding:utf-8-*-
origin = [0, 0]  # 坐标系统原点
legal_x = [0, 50]  # x轴方向的合法坐标
legal_y = [0, 50]  # y轴方向的合法坐标
def create(pos=origin):
    print(pos)
    def player(direction, step):
		# 这里应该首先判断参数direction,step的合法性,比如direction不能斜着走,step不能为负等
		# 然后还要对新生成的x,y坐标的合法性进行判断处理,这里主要是想介绍闭包,就不详细写了。
		new_x = pos[0] + direction[0] * step
		new_y = pos[1] + direction[1] * step
		pos[0] = new_x
		pos[1] = new_y
		# 注意!此处不能写成 pos = [new_x, new_y],否则外层参数pos也不会改变,执行完就会释放内部函数参数pos,原来的pos也不会改变。
		return pos
    return player
	
player = create()  # 创建棋子player,起点为原点
print(player([1, 0], 10))  # 向x轴正方向移动10步
del player
player1 = create()
输出结果:
		[0, 0]
		[10, 0]
		[10, 0]

分析:可以看到我删除函数后再次调用,pos的值竟然没有被释放。这便是闭包的作用:携带环境(包)。

2.装饰器
意义:不影响原有函数的功能,还能添加新的功能
如果只有两层函数
那么在闭包函数最外层用来接收被装饰函数,以及你这个 想存放内容,最内层可以接收被装饰函数的参数,返回值需要是fun()才会执行被装饰函数。

def fun1(fun):#定义一个fun来接收被装饰函数
	def fun2(*args, **kwargs):#接收被装饰函数参数
	    ...
	    return fun(*args, **kwargs)#执行被装饰函数
	return fun2
			    
@fun1()
def hello(a,b):
	pass

如果装饰器里带有参数,那么则在外部多加一层用来接收参数,如下

def fun1(a):
    ...
    def fun2(fun):
		def fun3(*args, **kwargs):
 		    ...
	  	  	return fun(*args, **kwargs)
		return fun3
    return fun2

@fun1(a = 'a')
def hello(b,c):
    pass

@fun(a = ‘a’)相当于fun(a=‘a’)(),因此执行@fun(a= ‘a’)得到的结果的其实就是fun3,
这个时候我再调用函数的时候直接执行fun3(),必须返回值是我传入函数的调用fun(*args, **kwargs),而不是函数名fun,才会执行被装饰的函数。

代码运行:
装饰器会改变被装饰函数的一些原信息,比如此处,调用
hello(x,y)
print(hello.__name__),输出变成了fun3,而不是hello,这个便是装饰器的问题,所以才有了Flask中@wrap使用保留被装饰函数一些特有信息。

那么装饰器的作用:
函数添加装饰器后,设置断点调试可以看到调用hello()会直接进入执行fun3()函数,那么我们可以在fun3中定义一些在执行被装饰函数之前的一些入口条件。这便是装饰器的作用

这里没有赘述很多原理,只是从简单的作用来解释闭包和装饰器,仅作参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值