当前位置:
首页 > temp > 简明python教程 >
-
Python装饰器(2)
2)
return formatResult
return wrapper
def add(a:float,b:float)->float:
return a+b
print(add(12.09,19.12345))
其输出结果如下所示:
31.21
通过装饰器,我们很快就达到要求。但有些情况,单纯的数值可能并没有太大意义,需要结合单位。假设上面示例返回为重量,则单位可能为g、kg等。那这种需求有没有解决办法了?示例代码如下所示:
def unit(unit:str)->str:
def digitalFormat(func):
def wrapper(*args,**kwargs):
result=func(*args,**kwargs)
formatResult=f"{round(result,2)} {unit}"
return formatResult
return wrapper
return digitalFormat
@unit("kg")
def add(a:float,b:float)->float:
return a+b
print(add(12.09,19.12345))
其输出结果如下所示:
31.21 kg
如果装饰饰器本身需要传递参数,那么再定义一层函数,将装饰的参数传入即可,是不是很简单。
2.3.5 类装饰器
1.使用类去装饰函数
前面实现的装饰器都是针对函数而言,在实际应用中,类也可以作为装饰器。在类装饰器中主要依赖函数__call__(),每调用一个类的示例时,函数__call__()就会被执行一次,示例代码如下所示:
class Count:
def __init__(self,func):
self.func=func
self.callCount=0
def __call__(self, *args, **kwargs):
self.callCount+=1
print(f"call count is {self.callCount}")
return self.func(*args,**kwargs)
@Count
def testSample():
print("Hello, Surpass")
for i in range(3):
print(f"first call {testSample()}")
其输出结果如下所示:
call count is 1
Hello, Surpass
first call None
call count is 2
Hello, Surpass
first call None
call count is 3
Hello, Surpass
first call None
2.使用函数去装饰类
def decorator(num):
def wrapper(cls):
cls.callCount=num
return cls
return wrapper
@decorator(10)
class Count:
callCount = 0
def __init__(self):
pass
def __call__(self, *args, **kwargs):
self.callCount+=1
print(f"call count is {self.callCount}")
return self.func(*args,**kwargs)
if __name__ == '__main__':
count=Count()
print(count.callCount)
其输出结果如下所示:
10
2.4 何时使用装饰器
这个需要据实际的需求而定。比如需要测试每个函数运行时间,此时可以使用装饰器,很轻松就能达到。另外装饰器也可应用到身价认证、日志记录和输入合理性检查等等。
2.5 装饰器实际案例
在实际工作中,装饰器经常会用来记录日志和时间,示例如下所示:
from functools import wraps
import logging
import time
def logType(logType):
def myLogger(func):
logging.basicConfig(filename=f"{func.__name__}.log",level=logging.INFO)
@wraps(func)
def wrapper(*args,**kwargs):
logging.info(f" {logType} Run with args:{args} and kwargs is {kwargs}")
return func(*args,**kwargs)
return wrapper
return myLogger
def myTimer(func):
@wraps(func)
def wrapper(*args,**kwargs):
startTime=time.time()
result=func(*args,**kwargs)
endTime=time.time()
print(f"{func.__name__} run time is {endTime-startTime} s ")
return result
return wrapper
@logType("Release - ")
@myTimer
def testWrapperA(name:str,color:str)->None:
time.sleep(5)
print(f"{testWrapperA.__name__} input paras is {(name,color)}")
@logType("Test - ")
@myTimer
def testWrapperB(name:str,color:str)->None:
time.sleep(5)
print(f"{testWrapperB.__name__} input paras is {(name,color)}")
if __name__ == '__main__':
testWrapperA("apple","red")
testWrapperB("apple", "red")
其输出结果如下所示:
testWrapperA input paras is ('apple', 'red')
testWrapperA run time is 5.000441789627075 s
testWrapperB input paras is ('apple', 'red')
testWrapperB run time is 5.000349521636963 s
日志记录信息如下所示:
3.小结
装饰器就是接受参数类型为函数或类并返回函数或类的函数,通过装饰器函数,在不改变原函数的基础上添加新的功能。
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程
检测数据类型的四种方法
js中数组的方法,32种方法
前端操作方法
数据类型
window.localStorage.setItem 和 localStorage.setIte
如何完美解决前端数字计算精度丢失与数