【问题标题】:Monkey patching a module function depending on another function inside the module猴子根据模块内的另一个功能修补模块功能
【发布时间】:2014-08-29 03:16:27
【问题描述】:

我的模块中有一个函数损坏了

破碎的.py

def brokenfunc():
    dependency()


def dependency():
    print "hello"

例程依赖于另一个函数依赖,这很好。我需要猴子补丁损坏,所以在另一个模块中我做了

补丁.py

import broken

def brokenfunc():
    print "patched"

    dependency()

brokenfunc.__globals__["dependency"]=broken.brokenfunc.__globals__["dependency"]
broken.brokenfunc = brokenfunc

broken.brokenfunc()

显然,我必须重写全局变量,因为修补函数中的依赖关系是在修补模块中定义的,并且会在那里寻找依赖关系。

这行得通,但我对这个 hack 不满意。我试图更新整个 globals 字典,但在这种情况下,我覆盖太多并且损坏的函数继续运行。这是正确的做法(也考虑极端情况)还是有另一种正确的策略?

【问题讨论】:

    标签: python


    【解决方案1】:

    你可以在你的新函数中引用依赖:

    import broken
    
    def brokenfunc():
        print "patched"
    
        broken.dependency()
    
    broken.brokenfunc = brokenfunc
    

    或者您可以通过导入将dependency 添加到您的模块全局变量中:

    import broken
    from broken import dependency
    
    def brokenfunc():
        print "patched"
    
        dependency()
    
    broken.brokenfunc = brokenfunc
    

    真的没必要这么费劲; brokenfunc.__globals__ 只是你当前的模块命名空间

    【讨论】:

    • 是的。今天我赢得了“如何让我的生活更复杂”奖
    • 除了我在__globals__ 中覆盖的原因是嘲笑。有什么我应该注意的极端情况吗? (免责声明:我已经尝试过mockminimock,但它们并没有如我所愿,所以我手动进行)。 Data model 表示 属性(引用本身)是只读的。
    • 为什么还要坚持访问__globals__?访问模块命名空间有更多可读的方法,甚至是动态的。改用mock 更加努力。
    • 我猜它可能不是模块命名空间,在嵌套定义的情况下,如将其称为非本地。不过你说的有道理,我不知道动态方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-17
    • 1970-01-01
    • 2013-11-01
    • 2012-09-19
    • 2014-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多