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

Python类方法装饰器传递实例变量参数的实现方案

问题描述

我有如下Python类:

class MatrixOfCarriers(DataLoader):
    def load_data(self):
        brands = self.brands
        try:
            data = self._load_data()
            print("'Carrier Matrix' data loaded successfully.\n")
        except Exception as e:
            print(
                "\nCouldn't load 'Carier Matrix' data due to the following "
                + "error: '{}'".format(str(e))
            )
            raise e

        return data

我想用如下装饰器装饰MatrixOfCarriers.load_data方法:

def cast_pct_buffer_columns(brands):
    def inner(func):
        def wrapper(*args, **kwargs):
            data = func(*args, **kwargs)

            for brand in func.brands.values():
                if brand["pct_buffer_column"] in data.columns:
                    data[brand["pct_buffer_column"]] = (
                        pd.to_numeric(
                            data[brand["pct_buffer_column"]].str.replace(
                                "[,%]", "", regex=True
                            )
                        )
                        / 100
                    )

            return data

        return wrapper

    return inner

问题在于该装饰器需要的参数brands是类的实例变量,但无法通过@cast_pct_buffer_columns(self.brands)传递,因为self在实例方法外部不在作用域内。我还尝试在load_data方法内设置brands = self.brands,再在装饰器中调用func.brands,但也无效。请问该如何解决?

解决方案

你可以调整装饰器的实现,让它从实例方法的第一个参数(也就是self)中直接获取brands变量,无需在装饰时传递参数。

修改后的装饰器

def cast_pct_buffer_columns(func):
    def wrapper(self, *args, **kwargs):
        # 从当前实例中获取brands变量
        brands = self.brands
        # 执行原方法获取数据
        data = func(self, *args, **kwargs)

        # 处理百分比列转换逻辑
        for brand in brands.values():
            col_name = brand["pct_buffer_column"]
            if col_name in data.columns:
                data[col_name] = (
                    pd.to_numeric(
                        data[col_name].str.replace("[,%]", "", regex=True)
                    )
                    / 100
                )

        return data
    return wrapper

装饰类方法的正确方式

直接在load_data方法上使用装饰器即可,无需额外传递参数:

class MatrixOfCarriers(DataLoader):
    @cast_pct_buffer_columns
    def load_data(self):
        try:
            data = self._load_data()
            print("'Carrier Matrix' data loaded successfully.\n")
        except Exception as e:
            print(
                "\nCouldn't load 'Carrier Matrix' data due to the following "
                + "error: '{}'".format(str(e))
            )
            raise e

        return data

核心逻辑说明

  • 实例方法的第一个参数固定为self(代表当前类的实例),所以装饰器的wrapper函数可以直接通过self访问实例变量brands,绕开了装饰时无法引用self的问题。
  • 原装饰器的三层嵌套结构可以简化为两层,因为不再需要接收外部传入的brands参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 00:40:43