Python: 使 lib 使用重新定义 class

Python: make lib use redefined class

想象一下使用 python 库。假设这个库有一个脚本和几个感兴趣的 classes。所有这些 classes 都在单独的文件中定义。假设 class D 被 class A,B,C 以多种方式导入和使用。以同样的方式 class A 使用 class B,class B 使用 class C。脚本直接使用 class A,因此直接和间接使用class D。现在假设您要自定义 D 并在本地定义一个派生自 class D 的 class D'。

制作脚本和其他 classes(A、B、C)使用 class D' 而不是 D 的最优雅方法是什么?

谢谢你,祝你有美好的一天!

你可以monkey patch the library.

# a.py
import d
class A():
    my_d = d.D()

# script.py
A.d.D = D_prime

def foo():
    a_cls = a.A() # uses A.d.D is D'

a.py 导入 D 的方式很重要

# a.py
from d import D
class A():
    my_d = D()

# script.py
A.D = D_prime

def foo():
    a_cls = a.A() # uses A.D is D'

其他导入方案可能涉及类似的模式。像这样的东西可能很难修补。

def builder():
    from d import D
    return D()

查看 mock library does this. If it's a toy, you could use this directly. patch in particular is interesting.

的方式可能也会有所帮助
@patch('A.d.D', new=D_prime)
def my_func(...):
    a = A() # a.d.D is D_prime

猴子补丁是一种代码味道,取决于应用程序代码中的单元测试是一种味道。 None 其中 "elegant"。如果您是库作者,请改为支持依赖注入。

如果您够勇敢,您可以将一些补丁装饰器拉出到不专注于模拟的东西中。因为这个模式存在于 unittest 库中,所以它可以被认为是 pythonic 和 "elegant" 上面的警告。

如果您对 的工作原理感兴趣,您正在修改模块 a 的符号 table。有关详细信息,请参阅 globals and locals