保留装饰函数的签名
装饰器是增强 Python 函数功能的强大工具。然而,它们有时会掩盖原始函数的签名。这可能会给文档、调试和自动化工具带来问题。
问题:
考虑一个将所有参数转换为整数的通用装饰器:
<code class="python">def args_as_ints(f): def g(*args, **kwargs): args = [int(x) for x in args] kwargs = dict((k, int(v)) for k, v in kwargs.items()) return f(*args, **kwargs) return g</code>
虽然装饰按预期工作,但装饰函数的签名被替换为“args,*kwargs”,丢失了有关原始参数的信息。
解决方法:
存在多种解决方法,但没有一个完全令人满意:
解决方案:
装饰器模块提供了一个优雅的解决方案:
<code class="python">import decorator @decorator.decorator def args_as_ints(f, *args, **kwargs): args = [int(x) for x in args] kwargs = dict((k, int(v)) for k, v in kwargs.items()) return f(*args, **kwargs)</code>
这个装饰器通过将原始函数的签名作为参数传递给被包装的函数来保留原始函数的签名。
改进的装饰器:
<code class="python">@args_as_ints def funny_function(x, y, z=3): """Computes x*y + 2*z""" return x*y + 2*z</code>
现在,装饰函数funny_function 保留其原始签名:
>>> help(funny_function) Help on function funny_function in module __main__: funny_function(x, y, z=3) Computes x*y + 2*z
Python 3.4 :
对于 Python 3.4 及更高版本,functools.wraps 提供了类似的解决方案:
<code class="python">import functools def args_as_ints(func): @functools.wraps(func) def wrapper(*args, **kwargs): args = [int(x) for x in args] kwargs = dict((k, int(v)) for k, v in kwargs.items()) return func(*args, **kwargs) return wrapper</code>
通过使用这些技术,装饰器可以增强函数功能,同时保留其原始签名,确保代码库的清晰度和一致性。
以上是在 Python 中使用装饰器时如何保留函数签名?的详细内容。更多信息请关注PHP中文网其他相关文章!