You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Python类内部的实例方法装饰该类的其他成员方法

类内方法装饰实例方法的解决方案

问题根源

你代码报错的核心原因是:装饰器@foo的执行时机是类定义阶段,此时还没有任何Foobar类的实例被创建,被定义为实例方法的foo无法接收到实例self,只会把被装饰的bar函数作为第一个参数传入,自然就没有值传给func形参。

注意:你原代码中print(self + " is doing something")的写法会报错,因为实例对象不能直接和字符串做拼接操作,需要先转为字符串,后续示例中使用f-string自动完成了类型转换。

可行方案

方案1:调整装饰器定义,在包装函数中获取实例

改动最小,完全满足你需要访问实例self的需求:

class Foobar:
    # 类定义阶段没有实例,装饰器不需要接收self参数
    def foo(func):
        # 包装函数的第一个参数就是调用bar时传入的实例对象
        def wrapped(self, *args, **kwargs):
             print(f"{self} is doing something")
             func(self, *args, **kwargs)
        return wrapped
    
    @foo
    def bar(self, *args, **kwargs):
        print("Foobar")

如果不希望foo被外部调用,可以将其重命名为私有命名_foo即可。

方案2:实例初始化阶段手动装饰

如果你必须保留foo作为实例方法的定义(比如需要单独调用foo完成其他装饰逻辑),可以把装饰操作移到__init__方法中,等实例创建完成后再执行装饰:

class Foobar:
    def __init__(self):
        # 实例创建完成后,用当前实例的foo方法装饰bar
        self.bar = self.foo(self.bar)
    
    def foo(self, func):
        def wrapped(*args, **kwargs):
             print(f"{self} is doing something")
             func(*args, **kwargs)
        return wrapped
    
    # 此处不需要加装饰器
    def bar(self, *args, **kwargs):
        print("Foobar")

内容的提问来源于stack exchange,提问作者user16519472

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 20:21:03