使用__setattr __重写库类别类别的整个方法:缺少1所需的位置参数:' self'
我有一些带有棘手结构的导入软件包 并需要调用一些基于许多其他方法的方法 使用非默认参数,这不是类,将它们像sklearn中的管道一样归因于他们。
此模块结构的最小示例:
class Library_class:
def __init__(
self,
defined_class_options,
):
self.defined_class_options = defined_class_options
def method1( self , default_non_class_arg = 12 ):
assert self.defined_class_options==3
return default_non_class_arg
def method2( self, image ):
return image/ self.method1()
默认用法:
class_instance = Library_class( 3 )
class_instance.method2( 36 )
> 3.0
例如,我需要将DEFAULT_NON_CLASS_ARG设置为6。
我已经尝试了多种方法:
class_instance.method2( 36 ,
method1__default_non_class_arg=3 )
typeerror:method2()有一个意外的关键字参数'method1__default_non_class_arg'
它可能无法正常工作,因为重新定义函数上的class肯定没有
- setAttr
class_instance.__setattr__('method1',Library_class.new_method1)
class_instance.method2( 36 )
set_paramstypeerror:new_method1()缺少1所需的位置参数:'self'
I've got some imported packages with tricky structure
and need to call some method that bases on lots of other methods
with non-default parameters, which are not class attributes themself like pipeline in sklearn.
Minimal example of this module structure:
class Library_class:
def __init__(
self,
defined_class_options,
):
self.defined_class_options = defined_class_options
def method1( self , default_non_class_arg = 12 ):
assert self.defined_class_options==3
return default_non_class_arg
def method2( self, image ):
return image/ self.method1()
Default usage:
class_instance = Library_class( 3 )
class_instance.method2( 36 )
> 3.0
I need to set default_non_class_arg to 6 for example.
I've tried multiple approaches:
- Analogous to https://stackoverflow.com/a/35634198/7607734
class_instance.method2( 36 ,
method1__default_non_class_arg=3 )
TypeError: method2() got an unexpected keyword argument 'method1__default_non_class_arg'
It don't work probably because class definitely don't have set_params
- With setattr on redefined function
class_instance.__setattr__('method1',Library_class.new_method1)
class_instance.method2( 36 )
TypeError: new_method1() missing 1 required positional argument: 'self'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的片段和问题都非常凌乱,几乎是不可读的地步。
无论如何,如果您希望将
method1
替换为另一个功能,则在特定实例中saynew_method1
,请执行此操作。您呼叫.__ setAttr __
这样做,但根本不需要(如果是,由于您没有在代码写入时间替换名称的方法,并且需要它作为一个参数,调用内置setAttr
,而不是实例方法:`setAttr(class_instance,“ method1”,new_method1')。通常,如果您知道,请在代码签名时您必须在一个实例中替换“方法1”,评估操作员将执行此操作:
class_instance.method1 = new_method1
审查中的问题是,如果您将方法分配给实例,而不是类,您正在绕过Python用来将
self
属性插入其中的机制 - 因此您的new_method1需要其他签名(这正是错误消息“ typeerror:new_method1()缺少1个缺失1位置论点:“自我”在说):这将起作用。
new_method1
也可以写在班级主体中,并且可以替换相同,但是您必须在没有self
参数的情况下编写它,然后不会作为正常方法直接起作用。或者,您可以在评估时插入
self
参数自己 -functools.partial
调用是一种方便的方法:类myclass: class myclass:
...
def方法1(self,param1 = 36):
...
my_instance = myClass()
来自functools导入部分
myClass.method1 = partial(myClass.new_method1,my_instance)
,这应该回答您要问的内容,但是在不说这不是一个好设计的情况下结束答案并不诚实。最好的方法是从另一个地方提取您的参数,它可能是从实例属性中提取的,而不是完全替换该方法只是为了更改它。
由于对于普通属性,如果不存在实例属性,Python将读取类属性,它将自然发生,而您要做的就是在您的实例中设置新的默认值。
Both your snippets and question are quite messy, almost to the point of being unreadable.
Anyway, if you wantt to replace
method1
with another function, saynew_method1
in an specific instance, just do that. Your call to.__setattr__
does that, but it is not needed at all, (and if it was, due to you not having the method to be replaced name at code writting time, and needed it as a parameter, it is more correct to call the built-insetattr
, not the instance method: `setattr(class_instance, "method1", new_method1").Ordinarily, if you know, at code writting time you have to replace "method1" in an instance, the assigment operator will do it:
class_instance.method1 = new_method1
What went wrong in your examle is that if you assign a method to an instance, instead of a class, you are bypassing the mechanism that Python uses to insert the
self
attribute into it - so your new_method1 needs a different signature. (and this is exactly what the error message "TypeError: new_method1() missing 1 required positional argument: 'self'" is saying):this will work.
new_method1
could be written in a class body as well, and could be replaced just the same, but you would have to write it without theself
parameter the same, and then it would not work straight as a normal method.OR, you can, at assigment time, insert the
self
argument yourself - thefunctools.partial
call is a convenient way to do that:class MyClass:
...
def method1(self, param1=36):
...
my_instance = MyClass()
from functools import partial
MyClass.method1 = partial(MyClass.new_method1, my_instance)
Now, this should answer what you are asking, but it would not be honest of me to end the answer without saying this is not a good design. The best thing there is to pull your parameter from another place, it might be from an instance attribute, instead of replacing the method entirely just to change it.
Since for normal attributes, Python will read the class attribute if no instance attribute exists, it will happen naturally, and all you have to do is to set the new default value in your instance.