python - 如何在不更改参数名称的情况下修饰 Python 函数?

标签 python python-decorators keyword-argument

以下 Python 代码定义了一个记录器和一个阶乘函数,然后使用关键字参数调用阶乘函数:

def logger(f):
  def f_(a):
    print("Call", a)
    return f(a)
  return f_

# @logger # uncomment this line to see the problem
def factorial(n):
  return 1 if n == 0 else n * factorial(n-1)

print(factorial(n=5))

产生以下输出(如预期):120

现在,如果我取消注释记录器装饰器,则会收到错误,因为参数的名称已变为 a 而不是 n:

如何在不更改参数名称的情况下修饰函数(如阶乘)?

最佳答案

忽略装饰器语法,这就是您正在做的事情:

def logger(f):
    def f_(a):
        print("Call", a)
        return f(a)
    return f_

def factorial(n):
    return 1 if n == 0 else n * factorial(n-1)

# `factorial` is `def f_(a):` now
factorial = logger(factorial)

因此,为了简单地解决此问题,请使用相同的声明,或者不使用关键字参数(n=5)


纠正此问题的更好方法是在内部函数中使用解包:

import functools

def logger(f):
    @functools.wraps(f)
    def f_(*args, **kwargs):
        print("Call", f.__name__, *args, *[f"{k}={v!r}" for k, v in kwargs.items()])
        return f(*args, **kwargs)
    return f_

Here's a useful article on the topic.

关于python - 如何在不更改参数名称的情况下修饰 Python 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53521993/

相关文章:

python - *args 和 **kwargs 的使用

python - 如何将 float 转换为时分秒?

python - 是否可以在 python 函数中强制数据不变性?

Python 装饰器,自己搞混了

python - 使用装饰器将参数传递给 python 函数时出现问题

python-3.x - **Kwargs 0 位置参数错误

Python 通过 xml 抓取打印空括号

python - 保护在 Python 上运行的 .exe 程序源代码的最佳方法?

python - Visual Studio Code 智能感知不显示修饰函数的参数

python - 如何打印 args 和 kwargs 列表