装饰一个参数不能按预期工作的函数

Decorating a function with parameters not working as expected

我有一个装饰器必须向字符串添加 HTML 标签。 如果必须包装固定字符串,装饰器工作正常。

def tagger(fn):
    def wrapper(*x):
        return "<strong>" + fn() + "</strong>"
    return wrapper

@tagger
def foo():
    return 'Hello'

print(foo())     

但是如果我删除固定字符串并向函数添加参数foo(),装饰器将不起作用。

def tagger(fn):
    def wrapper(*x):
        return "<strong>" + fn() + "</strong>"
    return wrapper

@tagger
def foo(x):
    return str(x)

print(foo('Hello'))     

我做错了什么?

您错过了将任何 *args 转发到 fn() 调用中。

def tagger(fn):
        def wrapper(*x):
               return "<strong>" + fn(*x) + "</strong>"  # <-- This will call foo(*x)
        return wrapper
@tagger
def foo(x):
    return str(x)

print(foo('Hello'))

你从不传递参数。包装器中的表达式 fn() 是对原始修饰函数的调用,但您不传递参数。

您的装饰器包装器接受任意位置参数作为 *x,将它们传递给 fn() 调用:

def tagger(fn):
    def wrapper(*x):
        return "<strong>" + fn(*x) + "</strong>"
    return wrapper

为了完成,您还想传递 关键字 参数,并为这些变量使用更常见的 argskwargs 名称:

def tagger(fn):
    def wrapper(*args, **kwargs):
        return "<strong>" + fn(*args, **kwargs) + "</strong>"
    return wrapper

现在装饰器也可以用于带有关键字参数的函数。