【问题标题】:TypeError: 'str' object is not callable error has occurred - Why?TypeError: 'str' object is not callable 发生错误 - 为什么?
【发布时间】:2020-12-15 23:14:57
【问题描述】:

从未听说过装饰器。正在学习引用此内容的 Udemy 课程 - https://pybit.es/decorators-by-example.html。正在遵循示例。只尝试使用一个装饰器,但在出现错误时停止。

  1. bar 输出正确
  2. bork 输出正确
  3. barf 引发错误

找到 stackoverflow 线程 - Why TypeError: 'str' object is not callable error has occurred in my code - 但它没有解释为什么 bork 有效,但 barf 无效。仍在阅读可能的 stackoverflow 线程以寻找可能的答案。

使用 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 也能正常工作?谢谢。

【问题讨论】:

  • 您的代码对于任何最近的 python 3 以及直接使用 python 而不是通过 IDLE 运行时的行为都是相同的。因此标签编辑。
  • 我很感激 - 原始的 pybit 文章示例引用了 11 年前的 stackoverflow 线程 - 我不确定它是为哪个版本的 Python 编写的,因此标记为 python-3.x,但是我使用的是 3.8.2,所以我包含了 python-3.8 的标签,因为我不确定是否应该忽略哪一个。谢谢指正!

标签: python-3.x typeerror python-decorators


【解决方案1】:

在您的 makebold 装饰器中,您正在调用返回对象,这是不正确的做法。您想返回未调用的对象。

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

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

【讨论】:

    猜你喜欢
    • 2019-11-27
    • 2011-04-26
    • 2017-01-23
    • 1970-01-01
    • 2013-05-28
    • 2021-02-03
    • 2016-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多