Python装饰器类方法报错求助:'str'对象不可调用
问题分析与修复
错误原因
你编写的wrapper_f装饰器逻辑完全错误:
- 调用
k.add('hello')时,实际执行的是wrapper函数,它把传入的字符串'hello'误当作参数f(wrapper的参数定义为self, f: tp.Callable, *args, **kwargs) - 随后
wrapper尝试调用f(self, *args, **kwargs),但f是字符串'hello'而非可调用对象,因此抛出TypeError: 'str' object is not callable
另外,wrapper_f在这里完全多余,它不仅没有任何实际作用,还破坏了add方法的正常执行流程——add方法本身就是一个返回装饰器的函数,不需要额外包装。
修复后的代码
直接移除多余的wrapper_f装饰器即可,同时优化类型注解以符合PEP8规范:
import typing as tp class A: def __init__(self, n: str): self.__n__ = n self.__dict_path__: dict[str, tp.Callable[[], str]] = {} def add(self, name: str) -> tp.Callable[[tp.Callable[[], str]], tp.Callable[[], str]]: def decorator(f: tp.Callable[[], str]) -> tp.Callable[[], str]: self.add_new(name, f) return f return decorator def add_new(self, name: str, f: tp.Callable[[], str]) -> None: self.__dict_path__[name] = f def get(self, name: str) -> str: return self.__dict_path__[name]() k = A('Hallo') @k.add('hello') def help() -> str: return "Hello =)))" if __name__ == "__main__": print(k.get('hello')) # 输出: Hello =)))
额外说明
- 类名遵循PEP8规范改为大驼峰式的
A,类型注解更精确 add方法返回一个装饰器函数,该装饰器会将被装饰的函数注册到实例的__dict_path__字典中- 调用
k.get('hello')时,会取出对应的函数并执行,返回预期的字符串
内容的提问来源于stack exchange,提问作者Juro
相关产品推荐
相关产品推荐

