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

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

DDD
发布: 2024-10-17 16:59:58
原创
485 人浏览过

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

来源:php
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板