装饰器相关使用
每日分享:
生活总是让我们遍体鳞伤,可是后来,那些受伤的地方一定会变成我们最强壮的地方。
目录
一、装饰器
1. 装饰器的定义
就是给已有函数增加额外功能的函数,它本质上就是一个闭包函数
装饰器的功能特点:
- 不修改已有函数的源代码
- 不修改已有函数的调用方式
- 给已有函数增加额外的功能
2. 装饰器示例代码
-
# 装饰器实质上就是闭包,怎么判断装饰器:当闭包函数只有一个参数,并且该参数是函数类型,那么这就是一个装饰器
-
def func_out(func):
-
def inner():
-
print('登录了吗,就说话?')
-
func()
-
print('赶快登录')
-
return inner
-
-
-
def comment():
-
print("发表评论")
-
-
-
# 为了保证调用时名称不变,将闭包对象命名为函数同名
-
comment = func_out(comment)
-
comment()
- 闭包函数有且只有一个参数,必须是函数类型,这样定义的函数才是装饰器
- 写代码要遵循开放封闭原则,它规定已经实现的功能代码不允许被修改,但可以被扩展
3. 装饰器的语法糖写法
如果有多个函数都需要拓展功能,每次都需要编写comment = func_out(comment)这样的代码对已有函数进行装饰,就会比较麻烦。
所以就有了语法糖,其书写格式为:@装饰器名字
通过语法糖的方式也可以完成对已有函数的装饰
-
# 装饰器实质上就是闭包,怎么判断装饰器:当闭包函数只有一个参数,并且该参数是函数类型,那么这就是一个装饰器
-
def func_out(func):
-
def inner():
-
print('登录了吗,就说话?')
-
func()
-
print('赶快登录')
-
return inner
-
-
-
-
def comment():
-
print("发表评论")
-
-
-
# 为了保证调用时名称不变,将闭包对象命名为函数同名
-
# comment = func_out(comment)
-
comment()
可以发现,结果一模一样
说明:
- @装饰器名 就等价于 comment = func_out(comment)
- 装饰器的执行时间是加载模块时立即执行
二、装饰器的使用
1. 装饰器的使用场景
- 函数执行时间的统计
- 输入日志信息
2. 装饰器实现已有函数执行时间的统计
-
import time
-
-
-
def decorator(func):
-
def inner():
-
begin = time.time()
-
func()
-
end = time.time()
-
print("函数运行的时间:", end-begin)
-
return inner
-
-
-
-
def work():
-
for i in range(10000):
-
print(i)
-
-
-
work()
所以,装饰器可以在不改变函数源代码及调用方式的前提下,扩展函数功能
三、通用装饰器的使用
1. 装饰带有参数的函数
-
def decorator(func):
-
def inner(a, b):
-
print("正在努力计算中...")
-
func(a, b)
-
return inner
-
-
-
-
def add_num(num1, num2):
-
result = num1 num2
-
print(result)
-
-
-
add_num(1, 2)
-
-
2. 装饰带有参数和返回值的函数
-
# --------------------装饰器装饰带有返回值的函数----------------------
-
def decorator(func):
-
def inner(a, b):
-
print("正在努力计算中...")
-
sum1 = func(a, b)
-
return sum1
-
return inner
-
-
-
-
def add_num(num1, num2):
-
result = num1 num2
-
return result
-
-
-
sum2 = add_num(1, 2)
-
print(sum2)
3. 装饰带有不定长参数的函数
-
# --------------------装饰器装饰带有不定参数的函数---------------------------------
-
def decorator(func):
-
def inner(*args, **kwargs):
-
print("正在努力计算中...")
-
func(*args, **kwargs)
-
return inner
-
-
-
# *args:把元组里面的每一个元素,按照位置参数的方式进行传参
-
# **kwargs:把字典里面的每一个键值对,按照关键字的方式进行传参
-
-
def add_num(*args, **kwargs):
-
result = 0
-
for value in args:
-
result = value
-
for value in kwargs.values():
-
result = value
-
print(result)
-
-
-
add_num(1, 2, a=3)
4. 通用装饰器(不定长参数以及有返回值)
-
# --------------------通用装饰器---------------------------------
-
def decorator(func):
-
def inner(*args, **kwargs):
-
print("正在努力计算中...")
-
num = func(*args, **kwargs)
-
return num
-
return inner
-
-
-
-
def show():
-
return "你好!"
-
-
-
info = show()
-
print(info)
通过以上几类装饰器的书写,可以发现:
装饰器的内部函数inner与要装饰的函数保持一致即可,即装饰函数有参数,inner就有参数;装饰函数有返回值,inner就有返回值
四、多个装饰器的使用
-
def add_p(func):
-
def inner():
-
result = "<p>" func() "</p>"
-
return result
-
return inner
-
-
-
def add_div(func):
-
def inner():
-
result = "<div>" func() "</div>"
-
return result
-
return inner
-
-
-
-
-
def content():
-
return "人生苦短,我学python"
-
-
-
print(content())
说明:
- 多个装饰器的装饰:离函数最近的装饰器先装饰,然后外面的装饰器再对装饰后的函数进行装饰
五、带有参数的装饰器
带有参数的装饰器就是使用装饰器装饰函数的时候可以传入指定参数
语法格式:@装饰器(参数...)
在装饰器外面包裹上一个函数,让最外面的函数接收参数,返回的是装饰器
-
def logging(flag):
-
def decorator(func):
-
def inner(a, b):
-
if flag == " ":
-
print("正在进行加法运算...")
-
elif flag == "-":
-
print("正在进行减法运算...")
-
result = func(a, b)
-
return result
-
return inner
-
return decorator
-
-
-
-
def add(a, b):
-
result = a b
-
return result
-
-
-
-
def sub(a, b):
-
result = a - b
-
return result
-
-
-
print(add(1, 2))
-
print(sub(1, 3))
使用带有参数的装饰器,其实是在装饰器外面又包裹了一个函数,使用该函数接收参数,返回装饰器(@符号必须配合装饰器使用)
六、类装饰器
装饰器还有一种特殊的用法就是类装饰器,就是通过定义一个类来装饰函数
-
class Check(object):
-
-
def __init__(self, func):
-
# 初始化操作在此完成(将func设为私有)
-
self.__func = func
-
-
# 实现call方法,表示对象是一个可调用对象,可以像调用函数一样进行调用
-
def __call__(self, *args, **kwargs):
-
# 添加装饰功能
-
print("请先登录")
-
self.__func()
-
-
-
-
def comment():
-
print('发表评论')
-
-
-
comment()
说明:
- @Check等价于comment = Check(comment),所以需要提供一个init方法,并多增加一个func参数
- 要想类的实例对象能够像函数一样调用,需要在类里面使用call方法,把类的实例变成可调用对象,也就是说可以像函数一样调用
- 在call方法里对func函数进行装饰,可以添加额外的功能
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgiceka
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13