【问题标题】:Decorating a function with parameters not working as expected装饰带有参数的函数未按预期工作
【发布时间】:2021-02-05 13:46:25
【问题描述】:

我有一个必须将 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'))     

我做错了什么?

【问题讨论】:

  • fn() 呼叫foo()foo 需要一个参数,但你没有传递一个。您的意思是通过*x 吗? fn(*x).
  • TNX。我错过了。

标签: python python-decorators


【解决方案1】:

您错过了将任何 *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'))

【讨论】:

    【解决方案2】:

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

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

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

    为了完整起见,您还希望传递 keyword 参数,并为这些变量使用更常见的 argskwargs 名称:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-01
      • 2014-07-21
      • 2021-01-19
      • 2021-04-06
      • 1970-01-01
      • 2015-01-02
      • 2019-10-30
      • 2015-04-11
      相关资源
      最近更新 更多