首页  >  文章  >  后端开发  >  在 Python 中使用装饰器时如何保留函数签名?

在 Python 中使用装饰器时如何保留函数签名?

DDD
DDD原创
2024-10-17 16:59:58342浏览

How to Preserve Function Signatures When Using Decorators in Python?

保留装饰函数的签名

装饰器是增强 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”,丢失了有关原始参数的信息。

解决方法:

存在多种解决方法,但没有一个完全令人满意:

  • 手动将签名复制到文档字符串中。
  • 为每个特定签名创建一个新的装饰器。
  • 使用 exec 手动构造装饰函数。

解决方案:

装饰器模块提供了一个优雅的解决方案:

<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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn