TypeError: 'str' object is not callable error has occurred - Why?

TypeError: 'str' object is not callable error has occurred - Why?

从未听说过装饰器。正在学习引用此内容的 Udemy 课程 - https://pybit.es/decorators-by-example.html。正在效仿这个例子。只先尝试一个装饰器,但当我遇到错误时停止了。

  1. bar 输出正确
  2. bork 输出正确
  3. barf 报错

找到了 Whosebug 线程 - - 但它没有解释为什么 bork 有效而 barf 无效。仍在阅读可能的 Whosebug 线程以获得可能的答案。

使用 Python 3.8.2,在 IDLE 中工作。

from functools import wraps

def makebold(fn):
    @wraps(fn)
    def wrapped(*args, **kwargs):
        return "<b>" + fn(*args, **kwargs) + "</b>"
    return wrapped()

def hello3():
    foo = "hello world!"
    return foo

@makebold
def hello2():
    foo = "hello world!"
    return foo

print('test hello3\n') #should be 'hello world!'
bar = hello3()
print(bar)
print()
print('test makebold(hello3)\n') #should be '<b>hello world!</b>'
bork = makebold(hello3)
print(bork)
print()
print('test hello2 with decorator\n') #should be '<b>hello world!</b>'
barf = hello2()
print(barf)

我做错了什么?为什么 bork 工作,但 barf 引发错误?我如何更正此问题以使 barf 也能正常工作?谢谢。

在您的 makebold 装饰器中,您正在调用 return 对象,这是错误的做法。您想要 return 未调用的对象。

def makebold(fn):
    @wraps(fn)
    def wrapped(*args, **kwargs):
        return "<b>" + fn(*args, **kwargs) + "</b>"
    return wrapped  # <== HERE

当您在 returning 之前调用它时,当您调用 hello2() 时最终会发生什么,hello2 已经被评估为一个字符串,因此您最终调用了一个字符串。通过不在装饰器中调用 return 上的函数,您最终会使用 hello2() 调用函数。