详解Python实现同时支持带调用和不调用带装饰器
一般来说,不带参数装饰器,再使用时不加括号,带参数的装饰器使用时必须加括号。例如
- 不带参装饰器
def info(func): # 装饰器,参数接收一个函数,返回一个函数
@functools.wraps(func)
def wrapper(*args, **kwargs): # 与原函数功能一致,支持任意参数
print(f'调用函数: {func.__name__} 参数:{args} {kwargs}')
return func(*args, **kwargs) # 内部包裹调用原函数
return wrapper # 返回和原函数功能一致的函数
@info # 使用时不加括号
def add(a, b):
return a + b- 带参数的装饰器(返回装饰器的函数)
def info(show_result=True):
def _info(func): # 装饰器,参数接收一个函数,返回一个函数
@functools.wraps(func)
def wrapper(*args, **kwargs): # 与原函数功能一致,支持任意参数
print(f'调用函数: {func.__name__} 参数:{args} {kwargs}')
start_time = time.time()
result = func(*args, **kwargs) # 内部包裹调用原函数
if show_result is True:
print(f'调用结果: {result} 耗时: {time.time()-start_time}')
return result
return wrapper # 返回替换后的新函数
return _info
@info() # 即使使用默认参数也必须加括号调用(因为调用后才能得到装饰器)
def add(a, b):
return a + b注意: 带参数装饰器虽然通过参数支持定制,但是使用时必须加括号,用户很容易遗漏或分不清是否需要加括号
能不能像@pytest.fixture那样,既可以不带参数,也可以带参数使用呢,例如:
import pytest @pytest.fixture def a(): ... @pytest.fixture() def b(): ... @pytest.fixture(scope='module') def c(): ...
这就要求,我们装饰器外部函数,即可以本身作为一个装饰器(接收一个原函数,返回一个同功能函数),也可以根据参数调用后返回一个装饰器,实现如下:
def info(func=None, show_result=False): # 第一个参数为函数
def _info(func): # 装饰器,参数接收一个函数,返回一个函数
@functools.wraps(func)
def wrapper(*args, **kwargs): # 与原函数功能一致,支持任意参数
print(f'调用函数: {func.__name__} 参数:{args} {kwargs}')
start_time = time.time()
result = func(*args, **kwargs) # 内部包裹调用原函数
if show_result is True:
print(f'调用结果: {result} 耗时: {time.time()-start_time}')
return result
return wrapper # 返回替换后的新函数
if func is not None: # 不带括号(作为装饰器)使用时
return _info(func) # 返回 同功能函数wrapper(即_info的调用结果)
return _info # 否则,带括号调用(作为返回装饰器的函数)使用时,返回装饰器 _info
@info # 即使使用默认参数也必须加括号调用(因为调用后才能得到装饰器)
def add(a, b):
return a + b
@info()
def sub(a, b):
return a - b
@info(show_result=True)
def mul(a, b):
return a * b注意:1. 在使用装饰器info()不能手动指定第一个参数func=...
2. 在指定参数时,只能按key=value形式给出
到此这篇关于Python实现同时支持带调用和不调用带装饰器的文章就介绍到这了,更多相关python带调用和不调用带装饰器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
python操作SqlServer获取特定表的所有列名(推荐)
这篇文章主要介绍了python操作SqlServer获取特定表的所有列名,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2022-08-08
基于python实现自动化办公学习笔记(CSV、word、Excel、PPT)
这篇文章主要介绍了基于python实现自动化办公学习笔记,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2019-08-08
python构造icmp echo请求和实现网络探测器功能代码分享
本文分享了二个python示例,python构造icmp echo请求、实现网络探测器功能代码,类似nmap功能2014-01-01


最新评论