来自 class 和 __slots 的实例的 Monkeypatch 方法 __
Monkeypatch method of instance from class with __slots __
我一直在尝试解决第三方模块中的错误。该错误最近已修复,但我一直在想我的问题。也许这个问题对我或以后的其他人有帮助。
该模块定义了一个 class 运行时,其中包含我使用的几种方法。导入模块后,它会自动创建一个运行时实例,加载配置并将该实例提供给用户(我)使用。
# thirdPartyModule.py
class Runtime:
def __init__(self, a):
self.a = a
def configuration(self, ...):
...
def fun(self):
print(self.a)
rt = Runtime("twice")
rt.configuration(...)
不幸的是,其中一个运行时方法包含一个错误。我过去常常通过一个工作替代 like so:
覆盖实例的方法来修补这个错误
# mycode.py
import types
from thirdPartyModule import rt
def newfun(self):
print(self.a, self.a)
rt.fun = types.MethodType(newfun, rt)
rt.fun()
在我等待开发人员修复错误时,这工作得很好。或者至少它做到了开发人员将 __slots__
添加到 class:
# thirdPartyModule.py
class Runtime:
__slots__ = ("a", )
def __init__(self, a):
self.a = a
...
之后我在这个论坛尝试了几种方法覆盖方案,但都被拒绝了("AttributeError: 'Runtime' object attribute 'fun' is read-only")。
可能是 unittest.mock
can help me out,但我对 mocking 不太熟悉。我尝试了以下但没有成功:
import unittest.mock
rt.fun = mock.Mock(rt.fun, side_effect=newfun)
这会导致相同的 AttributeError。也许我可以模拟整个实例 (rt = mock.Mock(rt)
) 或类似的东西,但我对这种方法既不熟悉也不完全满意。
正如我所说,该错误已同时修复,但我不禁想知道在这种情况下您将如何处理?
>>> class X():
... __slots__ = ("a",)
... def func():
... print("1")
...
>>> x = X()
>>> type(x)
<class '__main__.X'>
>>> type(x).func = lambda self: print("2")
>>> x.func
<bound method <lambda> of <__main__.X object at 0x7f27fb88b050>>
>>> x.func()
2
>>>
说明:您必须对运行时 class 而不是实例进行 monkeypatch。
我一直在尝试解决第三方模块中的错误。该错误最近已修复,但我一直在想我的问题。也许这个问题对我或以后的其他人有帮助。
该模块定义了一个 class 运行时,其中包含我使用的几种方法。导入模块后,它会自动创建一个运行时实例,加载配置并将该实例提供给用户(我)使用。
# thirdPartyModule.py
class Runtime:
def __init__(self, a):
self.a = a
def configuration(self, ...):
...
def fun(self):
print(self.a)
rt = Runtime("twice")
rt.configuration(...)
不幸的是,其中一个运行时方法包含一个错误。我过去常常通过一个工作替代 like so:
覆盖实例的方法来修补这个错误# mycode.py
import types
from thirdPartyModule import rt
def newfun(self):
print(self.a, self.a)
rt.fun = types.MethodType(newfun, rt)
rt.fun()
在我等待开发人员修复错误时,这工作得很好。或者至少它做到了开发人员将 __slots__
添加到 class:
# thirdPartyModule.py
class Runtime:
__slots__ = ("a", )
def __init__(self, a):
self.a = a
...
之后我在这个论坛尝试了几种方法覆盖方案,但都被拒绝了("AttributeError: 'Runtime' object attribute 'fun' is read-only")。
可能是 unittest.mock
can help me out,但我对 mocking 不太熟悉。我尝试了以下但没有成功:
import unittest.mock
rt.fun = mock.Mock(rt.fun, side_effect=newfun)
这会导致相同的 AttributeError。也许我可以模拟整个实例 (rt = mock.Mock(rt)
) 或类似的东西,但我对这种方法既不熟悉也不完全满意。
正如我所说,该错误已同时修复,但我不禁想知道在这种情况下您将如何处理?
>>> class X():
... __slots__ = ("a",)
... def func():
... print("1")
...
>>> x = X()
>>> type(x)
<class '__main__.X'>
>>> type(x).func = lambda self: print("2")
>>> x.func
<bound method <lambda> of <__main__.X object at 0x7f27fb88b050>>
>>> x.func()
2
>>>
说明:您必须对运行时 class 而不是实例进行 monkeypatch。