【问题标题】:Does python's `unittest.mock.patch` mutate global state?python的`unittest.mock.patch`会改变全局状态吗?
【发布时间】:2015-01-08 16:24:02
【问题描述】:

我正在尝试确定 Python 的 mock.patch(Py3 中的 unittest.mock.patch)上下文管理器是否会改变全局状态,即它是否是线程安全的。

例如:假设一个线程使用上下文管理器在函数foo 中修补函数bar,然后在上下文管理器中,解释器暂停该线程(由于 GIL 等)并恢复另一个线程,这在所述上下文管理器之外运行foo。如果patch 是线程安全的,我希望函数foobar 的全局状态未被修改,因此第二个线程将获得foo 的正常行为。但是如果patch 修改了全局状态,第二个线程将获得foo 修改后的行为,即使它不在上下文管理器中。

我参考了源代码,但仅仅看它并不能清楚地分辨出来。

【问题讨论】:

    标签: python multithreading python-mock global-state


    【解决方案1】:

    mock.patch 本质上不是线程安全的或不是线程安全的。它修改一个对象。其实无非就是开头的赋值语句,结尾的撤销赋值语句。

    如果被修补的对象被多个线程访问,那么所有线程都会看到变化。通常,它用于修改模块的属性,即全局状态。以这种方式使用时,它不是线程安全的。

    【讨论】:

      【解决方案2】:

      我继续在 Python 3.4 上使用 multiprocessing.dummy.Pool 进行了粗略的实验。实验使用线程池将函数映射到 range(100) 输入,如果函数的输入正好是 10,它会修补一个内部函数以调用 time.sleep()。如果补丁是线程安全的,那么结果都会立即显示,除了 10 的结果会延迟显示;如果它不是线程安全的,那么一些结果会立即显示,而许多其他结果会延迟显示。

      结果表明unittest.mock.patch 确实改变了全局状态。很高兴知道!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-16
        • 1970-01-01
        • 1970-01-01
        • 2018-09-26
        • 1970-01-01
        • 2017-10-01
        • 2021-05-31
        • 1970-01-01
        相关资源
        最近更新 更多