具有 __slots __ 的类实例的 Monkeypatch 方法

1 python methods monkeypatching slots

我一直在尝试解决第三方模块中的错误。该错误最近已修复,但我一直想知道我的问题。也许这个问题将来会对我或其他人有所帮助。

该模块定义了一个类 Runtime,其中包含我使用的几种方法。导入模块后,它会自动创建一个运行时实例,加载配置并将该实例提供给用户(我)使用。

# 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(...)
Run Code Online (Sandbox Code Playgroud)

不幸的是,其中一个运行时方法包含一个错误。我曾经通过用一个工作替代品覆盖实例的方法来修补这个错误,如下所示

# mycode.py

import types
from thirdPartyModule import rt

def newfun(self):
    print(self.a, self.a)

rt.fun = types.MethodType(newfun, rt)
rt.fun()
Run Code Online (Sandbox Code Playgroud)

当我等待开发人员修复错误时,这一切都很好。__slots__或者至少在开发人员添加到类中之前它是这样的:

# thirdPartyModule.py

class Runtime:
    __slots__ = ("a", )

    def __init__(self, a):
        self.a = a

    ...
Run Code Online (Sandbox Code Playgroud)

从那时起,我在这个论坛上尝试了几种方法覆盖解决方案,但都被拒绝了(“AttributeError:'Runtime'对象属性'fun'是只读的”)。

这可能unittest.mock 可以帮助我,但我对嘲笑不太熟悉。我尝试了以下方法但没有成功:

import unittest.mock

rt.fun = mock.Mock(rt.fun, side_effect=newfun)
Run Code Online (Sandbox Code Playgroud)

这会导致相同的 AttributeError。也许我可以模拟整个实例 ( rt = mock.Mock(rt)) 或类似的东西,但我对这种方法既不熟悉也不完全满意。

正如我所说,该错误已同时得到修复,但我忍不住想知道在这种情况下你将如何进行?

Hac*_*ck5 6

>>> 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
>>> 
Run Code Online (Sandbox Code Playgroud)

说明:您必须对运行时类而不是实例进行猴子修补。