为何类内导入的不同模块函数调用时出现明显不一致报错
问题原因
Python的类属性如果是原生Python函数,会遵循描述符协议:当你通过类实例访问这个函数时,函数的__get__方法会被自动调用,返回一个绑定了当前实例的方法对象,调用的时候会自动把实例作为第一个参数(也就是self)传入。
numpy.sin是C语言实现的UFunc(通用函数)对象,没有实现对应的描述符逻辑,所以通过实例访问时不会触发绑定,你传入的参数就是实际收到的参数,因此调用正常。statsmodels的seasonal_decompose是标准Python函数,放在类属性中会触发绑定逻辑,你调用a4.seasonal_decompose([1, 2], period=1)时,实际收到的第一个参数是Foo4的实例a4,第二个参数才是你传入的数组,函数本来要求第一个参数是数值类的时间序列,拿到实例对象自然就报类型错误了。
解决方法
如果要直接把导入的函数作为类的属性调用,不需要自动传入实例参数,有两种成熟方案可选:
- 用
staticmethod装饰器标记导入的函数,明确告知Python不需要绑定self参数:
class Foo4: from numpy import sin from statsmodels.tsa.seasonal import seasonal_decompose # 标记为静态方法,不会自动注入self参数 seasonal_decompose = staticmethod(seasonal_decompose) sin = staticmethod(sin) # numpy函数也可统一添加,兼容性更好 a4 = Foo4() print(a4.sin(2)) print(a4.seasonal_decompose([1, 2], period=1))
- 保持你最开始Foo3的写法:在类的实例方法内部调用外部导入的函数,这种写法逻辑清晰,不会触发意外的参数绑定,适用所有场景。
内容的提问来源于stack exchange,提问作者jomurmiranda
相关产品推荐
相关产品推荐

