【问题标题】:Monkeypatch method of instance from class with __slots __带有 __slots __ 的类实例的 Monkeypatch 方法
【发布时间】:2020-06-09 21:20:00
【问题描述】:

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

该模块使用我使用的几种方法定义了一个类 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(...)

不幸的是,其中一个运行时方法包含错误。我过去常常通过一个工作替代 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__ 添加到类:

# thirdPartyModule.py

class Runtime:
    __slots__ = ("a", )

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

    ...

从那以后,我在这个论坛上尝试了几种方法覆盖的解决方案,但都被拒绝了(“AttributeError: 'Runtime' object attribute 'fun' is read-only”)。

可能是unittest.mockcan help me out,但我对嘲讽不太熟悉。我尝试了以下方法但没有成功:

import unittest.mock

rt.fun = mock.Mock(rt.fun, side_effect=newfun)

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

正如我所说,该错误已在此期间修复,但我不禁想知道您将如何处理这种情况?

【问题讨论】:

    标签: python methods monkeypatching slots


    【解决方案1】:
    >>> 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
    >>> 
    

    说明:您必须对 Runtime 类而不是实例进行猴子补丁。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多