关于使用__setattr__重写库类方法时出现“missing 1 required positional argument: self”错误的技术问询
解决方法:修改第三方类方法的默认参数而不修改原代码
针对你遇到的问题,这里有几个可行的方案,不需要改动原库的代码就能实现修改method1默认参数的需求:
方案1:使用functools.partial绑定新的默认参数
我们可以借助functools.partial给原方法绑定新的默认参数,同时保留实例的self绑定。具体步骤如下:
from functools import partial # 先创建原类实例 class_instance = Library_class(3) # 获取已绑定self的原method1,绑定新的默认参数 original_method1 = class_instance.method1 class_instance.method1 = partial(original_method1, default_non_class_arg=6) # 现在调用method2就会使用新的默认值 print(class_instance.method2(36)) # 输出 6.0
原理:class_instance.method1是已经绑定了当前实例self的方法对象,用partial给它添加默认参数后,新的方法在调用时如果没传default_non_class_arg,就会自动使用我们设置的6。
方案2:手动编写包装函数并绑定实例
如果不想依赖functools,也可以自己写一个包装函数,再把它绑定到实例上:
class_instance = Library_class(3) # 定义包装函数,修改默认参数,复用原方法逻辑 def wrapped_method1(self, default_non_class_arg=6): assert self.defined_class_options == 3 return default_non_class_arg # 将普通函数转换为绑定到实例的方法 import types class_instance.method1 = types.MethodType(wrapped_method1, class_instance) # 测试调用 print(class_instance.method2(36)) # 输出 6.0
这里用types.MethodType把普通函数转换成绑定到实例的方法,确保调用时self参数会自动传入,避免了之前出现的参数缺失错误。
方案3:子类化原类并重写方法
如果需要多次创建实例,子类化是更优雅且可复用的方式:
class ModifiedLibraryClass(Library_class): def method1(self, default_non_class_arg=6): # 直接调用父类方法并传入修改后的参数 return super().method1(default_non_class_arg=default_non_class_arg) # 使用子类创建实例 class_instance = ModifiedLibraryClass(3) print(class_instance.method2(36)) # 输出 6.0
这个方案的好处是所有子类实例都会自动使用新的默认参数,适合需要批量创建实例的场景。
为什么你之前的方法失败?
- 第一种方法用
method1__default_non_class_arg的风格,是sklearn等库特有的set_params配置机制,原类没有实现这个方法,所以无法识别这种参数格式。 - 第二种方法直接赋值
Library_class.new_method1,这是类的未绑定方法,没有关联到具体实例的self,所以调用时会提示缺少self参数。
内容的提问来源于stack exchange,提问作者MosQuan
相关产品推荐
相关产品推荐

