python中wraps函数用法详情
Python 函数 用法 详情
2023-09-11 14:15:15 时间
Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变)。
这样变化后对程序会造成一定的影响,如在flask框架中的一些函数添加自定义的decorator,添加后由于函数名和函数的doc发生了改变,这会对测试造成一定的影响。这是会可以使用functools包提供的wraps方法的decorator来消除这种副作用。写一个decorator的时候,在实现之前加上functools的wrap,它能保留原有函数的名称和docstring。
wraps是在装饰器中使用,保留原来函数的属性
functools.wraps
使用装饰器可以极大的复用了代码,但它也有一个缺点就是原函数的元信息不见了,比如函数的docstring、__name__、参数列表等。
示例代码1:
def logged(func):
def with_logging(*args, **kwargs):
print(func.__name__ + 'was called')
return func(*args, **kwargs)
return with_logging
@logged
def test():
"""
does some math
:param x:
:return:
"""
x = 6
return x ** 2
# 上述函数等价于
def test2():
"""
does some math
:param x:
:return:
"""
x = 5
return x ** 2
a = test()
print(a)
b = logged(test2)
print(b())
print("*" * 100)
print(test.__name__)
print(test.__doc__)
print("*" * 100)
print(test2.__name__)
print(test2.__doc__)
运行结果:
上述代码执行结果中不难看出,函数test被with_logging取代了,当然它的docstring,__name__等信息就变成了with_logging函数的信息了。
出现上述问题有时候是问题是挺严重的,这时候我们可以使用functools.wraps库,wraps本身也是一个装饰器,它能够把原函数的元信息拷贝到装饰器函数中,这使用装饰器函数也有原函数一样的元信息了。
示例代码2:
from functools import wraps
def logged(func):
@wraps(func)
def with_logging(*args, **kwargs):
print(func.__name__ + 'was called')
return func(*args, **kwargs)
return with_logging
@logged
def test():
"""
does some math
:param x:
:return:
"""
x = 6
return x ** 2
# 上述函数等价于
def test2():
"""
does some math
:param x:
:return:
"""
x = 5
return x ** 2
a = test()
print(a)
b = logged(test2)
print(b())
print("*" * 100)
print(test.__name__)
print(test.__doc__)
print("*" * 100)
print(test2.__name__)
print(test2.__doc__)
运行结果:
示例代码3:
from functools import wraps
def wrapper(func):
@wraps(func)
def inner(*args, **kwargs):
res = func(*args, **kwargs)
print("func.__name__:", func.__name__)
print("func.__doc__:", func.__doc__)
return res
return inner
@wrapper
def funcs():
"""funcs functions"""
pass
funcs()
print(funcs) # <function funcs at 0x0000026852CB4438>
运行结果:
示例代码4:
def wrapper(func):
def inner(*args, **kwargs):
res = func(*args, **kwargs)
print("func.__name__:", func.__name__)
print("func.__doc__:", func.__doc__)
return res
return inner
@wrapper
def funcs():
"""funcs functions"""
pass
funcs()
print(funcs) # <function wrapper.<locals>.inner at 0x0000021E46384438>
运行结果:
相关文章
- Python中python-nmap模块的使用
- python - 如何使用 Docker 运行多个 Python 脚本和一个可执行文件?
- Python kafka操作实例(kafka-python)
- python中chr()和ord()函数的用法
- python vars() 函数用法及实例
- Python isinstance() 函数用法及实例另类高级使用(附带classmethod 修饰符、json.dumps)
- python内置函数compile用法详解
- python中sort()和sorted()排序函数用法详解
- Python input函数
- 【python】+704个常用工具Python库
- Python爬虫-函数
- python之函数用法locals()
- python之函数用法execfile()
- python之函数用法all
- python之函数用法__str__()
- 《像计算机科学家一样思考Python》——3.11 有返回值函数和无返回值函数
- python 内置操作函数
- python Match函数
- Python 数据分析教程之如何验证线性回归的假设,线性回归的假设是什么?以及如何用python验证它们?
- 【转载】python的魔法方法———A Guide to Python's Magic Methods
- python之函数的基础用法
- python pandas自定义函数之apply函数用法
- python字符串find方法,python findall函数用法
- python六十一课——高阶函数之reduce
- Python列表函数和方法