1. 装饰器
1. 定义
给已有函数增加额外功能的函数,它本质上就是一个闭包函数。
2. 特点
- 不修改已有函数的源代码
- 不修改已有函数的调用方式
- 给已有函数增加额外的功能
3. 示例
# 外部函数
def func_out(func):
def func_in():
print("登录验证")
func()
# 返回内部函数
return func_in
def comment():
print("登陆成功")
comment = func_out(comment)
comment()
# 输出结果
登录验证
登陆成功
4. 装饰器的语法糖写法
# 外部函数
def func_out(func):
def func_in():
print("登录验证")
func()
# 返回内部函数
return func_in
@func_out # 装饰器的语法糖写法:@装饰器名称
def comment():
print("登陆成功")
comment()
# 输出结果
登录验证
登陆成功
2. 通用的装饰器
- 带有参数和返回值
def decorator(func): def inner(num1, num2): print("处理中……") return func(num1, num2) return inner @decorator def add(num1, num2): print(num1 + num2) return "处理结束" print(add(1, 2)) # 输出结果 处理中…… 3 处理结束
- 不定长参数和返回值
def decorator(func): def inner(*args, **kwargs): print("处理中……") # *args:把元组里面的每一个元素,按照位置参数的方式进行传参 # **kwargs:把字典里面的每一个键值对,按照关键字的方式进行传参 # 这里对元组和字典进行拆包,仅限于结合不定长参数的函数使用 return func(*args, **kwargs) return inner @decorator def add(*args, **kwargs): print(args) print(kwargs) return "处理结束" print(add(2, 1, 3, name="cb", age=18)) # 输出结果 处理中…… (2, 1, 3) {'name': 'cb', 'age': 18} 处理结束
3. 多个装饰器的使用
def make_div(func):
def inner():
return "<div>" + func() + "</div>"
return inner
def make_p(func):
def inner():
return "<p>" + func() + "</p>"
return inner
# 先执行make_p,再执行make_div
@make_div
@make_p
def content():
return "人生苦短,我用python!"
print(content())
# 输出结果
<div><p>人生苦短,我用python!</p></div>
4. 带有参数的装饰器
def rtn_decorator(msg):
def make_div(func):
def inner():
print(msg)
return "<div>" + func() + "</div>"
return inner
return make_div
@rtn_decorator("添加div标签")
def content():
return "人生苦短,我用python!"
print(content())
# 输出结果
添加div标签
<div>人生苦短,我用python!</div>
5. 类装饰器
class MyDecorator(object):
def __init__(self, func):
self.__func = func
# 实现__call__方法,让对象变成可调用的对象,可调用的对象能够像函数使用
def __call__(self, *args, **kwargs):
print("你好", end=",")
self.__func()
@MyDecorator
def prt_name():
print("cb")
prt_name()
# 输出结果
你好,cb