类内使用inference-schema装饰器报list index out of range错误
问题描述
我正在使用inference-schema包,将API调用传入的数据转换为格式正确的Pandas DataFrame。
当Run方法定义在类外部时,@input_schema装饰器运行完全正常;但我将逻辑完全一致的Run方法移入自定义类中后,调用方法时就会抛出list index out of range错误。
复现代码如下:
from numpy.core.numeric import NaN import pandas as pd from inference_schema.schema_decorators import input_schema from inference_schema.parameter_types.pandas_parameter_type import PandasParameterType def get_schema(): return pd.DataFrame({"Test": [ 0.0, NaN]}) @input_schema('df', PandasParameterType(get_schema())) def Run(df): return df['Test']*2 class Score: @input_schema('df', PandasParameterType(get_schema())) def Run(self, df): return df['Test']*2 score = Score() df = [{"Test": 21.0}] result = Run(df) # 类外定义的Run方法可正常运行 print(result) result = score.Run(df) # 类内逻辑完全一致的Run方法报错:'list index out of range' print(result)
需要实现预期的参数转换效果,可接受基于inference-schema的原生解决方案,也可推荐其他适用的Python工具包。
报错原因
@input_schema装饰器默认按普通函数的参数位置解析入参:普通函数Run(df)的第0位位置参数就是待转换的df,装饰器可正常读取入参完成格式转换;但类实例方法的第0位位置参数固定为代表实例本身的self,装饰器未做实例方法参数适配,仍将第0位参数识别为待转换的目标数据,实际拿到的是类实例对象,后续按DataFrame规则读取列时就会触发索引越界错误。
解决方案
方案1:基于inference-schema原生适配(无需更换依赖)
核心思路是避开装饰器直接修饰带self参数的实例方法,两种简单实现:
- 抽离独立转换函数:将加了装饰器的转换逻辑抽为类外的独立函数,类的实例方法内部直接调用该包装后的函数即可
# 定义核心处理逻辑 def _run_logic(df): return df['Test']*2 # 给逻辑加上schema转换装饰器 wrapped_run = input_schema('df', PandasParameterType(get_schema()))(_run_logic) class Score: def Run(self, df): return wrapped_run(df)
- 使用静态方法包装:在类内用
@staticmethod修饰被装饰的方法,静态方法无默认self参数,装饰器可正常识别,实例方法内部调用静态方法即可
class Score: @staticmethod @input_schema('df', PandasParameterType(get_schema())) def _wrapped_run(df): return df['Test']*2 def Run(self, df): return self._wrapped_run(df)
方案2:更换适配性更好的工具
如果没有强制依赖inference-schema的要求(比如特定云平台部署的schema生成要求),可以换用对类方法支持更好、维护更活跃的数据校验转换工具:
pydantic:通用Python数据校验工具,支持自动类型转换,和Pandas适配简单,普通函数、类方法、静态方法都可直接使用,无需额外处理参数位置问题pandera:专门面向Pandas生态的schema定义、校验、转换工具,原生支持类方法装饰器写法,可直接定义DataFrame的列类型、空值规则、取值范围,灵活性比inference-schema更高
内容的提问来源于stack exchange,提问作者Abra
相关产品推荐
相关产品推荐

