如何将Python类中的装饰器方法转换为独立类
类内装饰器方法转独立装饰器类的错误修正
原可运行代码(补全必要语法和导入)
from functools import wraps class MyClass(): class Decorators(): @classmethod def dekarait(cls, func): @wraps(func) def wrapper(instance, name: str, count: int = 0): print(name * count) func(instance) return wrapper def __init__(self) -> None: pass @Decorators.dekarait def good(self, name: str, count: int = 0) -> str: out: str = f"name:{name}" print("hello") return out
错误尝试代码
class MyClass(): class Dekarait(): def __init__(self, func): self.func = func def __call__(self, func): def wrapper(self, name: str, count: int = 0): print(name * count) func() return wrapper def __init__(self) -> None: pass @Dekarait def good(self, name: str, count: int = 0) -> str: out: str = f"name:{name}" print("hello") return out
问题核心分析
你没搞懂类作为装饰器的执行逻辑,错误点集中在:
__call__参数逻辑错误:用@Dekarait装饰方法时,会先创建Dekarait实例并保存被装饰的good方法;调用obj.good(...)时,实际是调用Dekarait实例的__call__,此时传入的是MyClass实例、name、count,而非错误的func参数。- 实例方法调用缺失绑定:原
good是实例方法,必须绑定MyClass实例才能执行,错误代码里func()没传实例参数,必然报错。 - 变量名冲突:
wrapper里的self和Dekarait类的self重名,导致逻辑混淆。
修正后的代码
from functools import wraps class MyClass(): class Dekarait(): def __init__(self, func): self.func = func wraps(func)(self) # 保留原函数的名称、文档等元信息 def __call__(self, instance, name: str, count: int = 0): # instance是MyClass的实例,对应原方法的self print(name * count) # 调用原方法必须传入实例,绑定实例方法 return self.func(instance, name, count) def __init__(self) -> None: pass @Dekarait def good(self, name: str, count: int = 0) -> str: out: str = f"name:{name}" print("hello") return out
关键修改点说明
__call__参数调整:明确接收MyClass实例作为第一个参数,后续是原方法的参数,符合装饰实例方法的调用逻辑。- 实例方法绑定调用:通过
self.func(instance, name, count)给原方法传入实例,保证实例方法能正常执行。 - 元信息保留:用
wraps(func)(self)复制原函数的元信息,避免装饰后函数名称、文档等被覆盖。 - 变量名清晰化:用
instance代替容易混淆的self,明确区分装饰器类实例和MyClass实例。
测试验证
运行以下代码可正常输出:
obj = MyClass() result = obj.good("test", 3) # 输出:testtesttest # hello print(result) # 输出:name:test
内容的提问来源于stack exchange,提问作者matt
相关产品推荐
相关产品推荐

