用于函数参数类型检查的装饰器如何在类内方法中正确使用
问题根因
- 类的实例方法默认第一个参数为类实例对象(通常命名为
self),你编写的print_dataframe(df)没有显式声明self参数,调用时第一个位置会自动传入Test类的实例,和你预期接收DataFrame的逻辑不符,同时和你@accepts(pd.DataFrame)声明的1个参数数量不匹配,触发断言错误。 - 类定义语法错误:
class Test()后缺少冒号:。
正确使用方法
方案1:声明为静态方法(无需访问类实例属性/方法的场景)
静态方法不会自动传入类实例对象,参数结构和普通函数完全一致,直接适配你现有的装饰器:
import pandas as pd def accepts(*types): def check_accepts(f): assert len(types) == f.__code__.co_argcount def new_f(*args, **kwds): for (a, t) in zip(args, types): assert isinstance(a, t), \ "arg %r does not match %s" % (a,t) return f(*args, **kwds) new_f.__name__ = f.__name__ return new_f return check_accepts class Test: @staticmethod @accepts(pd.DataFrame) def print_dataframe(df): print(df) # 调用测试 df = pd.DataFrame({'col1': [1,2,3]}) Test.print_dataframe(df) # 正常输出
方案2:保留为实例方法(需要访问类实例属性/方法的场景)
显式声明self参数,同时在accepts中补充self的类型声明:
import pandas as pd def accepts(*types): def check_accepts(f): assert len(types) == f.__code__.co_argcount def new_f(*args, **kwds): for (a, t) in zip(args, types): assert isinstance(a, t), \ "arg %r does not match %s" % (a,t) return f(*args, **kwds) new_f.__name__ = f.__name__ return new_f return check_accepts class Test: # 第一个参数对应self的类型,通用场景可写object,也可显式写Test @accepts(object, pd.DataFrame) def print_dataframe(self, df): print(df) # 调用测试 t = Test() df = pd.DataFrame({'col1': [1,2,3]}) t.print_dataframe(df) # 正常输出
内容的提问来源于stack exchange,提问作者Jame H
相关产品推荐
相关产品推荐

