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
相关产品推荐
相关产品推荐

