python函数之装饰器

1、什么是装饰器

装饰器是一个用来为被装饰者添加功能的工具
被装饰者:函数
装饰器:可以用函数实现装饰器这种工具

2、为何要用装饰器

为了在不修改被装饰器对象源代码以及调用方式的前提下,
	为被装饰对象添加上新功能

3、如何用装饰器

装饰器分为两种:
	无参装饰器和有参装饰器
无参装饰器基本步骤:
	def outter(func):
		def wrapper(*args,**kwargs):
    			res = func(*args,**kwargs)
    			return res
		return wrapper

	@outter
	def index(x):
		print('index')
		return 777     #return返回值可有可无,看需求,需不需要。
	index()
	ps:上述函数名不唯一,都是自己定义的,
有参装饰器基本步骤:
	def outter(x,y):
		def deco(func):
			def wrapper(*args,**kwargs):
				print(x,y)
				res = func(*args,**kwargs)
				return res
			return wrapper
		return deco
	@outter(111,22)
	def index():
		print('index')

	index()
	ps:上述函数名都是可以更改的,这只是一个框架,需要添加什么功能,加进去就可以

4、装饰器的补充:wraps
调用funcyools模块下的wraps函数,真正意义上将装饰完的index(这里的index信息指向的是wrapper的信息)的信息跟本来的函数index信息保持一致。
所有用def定义的函数都可以变,按自己定义的

from functools import wraps
def deco(func):
	@wraps(func) #加在最内层函数正上方
	def wrapper(*args,**kwargs):
		return func(*args,**kwargs)
	return wrapper

@deco
def index():
	'''哈哈哈哈'''
	print('from index')

res = index(111)
print(res)

5、叠加多个装饰器:
有时我们需要为一个函数添加多个不用的功能,那一个装饰器就不行了。
下面我们以无参装饰器为例,写下叠加多个装饰器的基本步骤

def deco1(func1):  # func1 = wrapper2的内存地址
	def wrapper1(*args, **kwargs):
		print('===>运行wrapper1')
		res1 = func1(*args, **kwargs)
		return res1
	return wrapper1

def deco2(func2):  # func2 = wrapper3的内存地址
	def wrapper2(*args, **kwargs):
		print('===>运行wrapper2')
		res2 = func2(*args, **kwargs)
		return res2
	return wrapper2

def deco3(func3):  # func3 = index的内存地址
	def wrapper3(*args, **kwargs):
		print('===>运行wrapper3')
		res3 = func3(*args, **kwargs)
		return res3
	return wrapper3

#                            index = wrapper1的内存地址
@deco1  # deco1(wrapper2的内存地址) -> wrapper1的内存地址
@deco2  # deco2(wrapper3的内存地址) -> wrapper2的内存地址
@deco3  # deco3(index的内存地址)  ->  wrapper3的内存地址
def index():
	print('from index')
	return 123
res = index()  # wrapper1()
print(res)
重要提示:叠加多个装饰器,1. 加载顺序(outter函数的调用顺序):自下而上
			2. 执行顺序(wrapper函数的执行顺序):自上而下
posted @ 2021-07-01 15:34  zhutianyu  阅读(93)  评论(0)    收藏  举报