可以用Python中的Context Manager全局替换函数吗?

时间:2012-04-30 18:04:52

标签: python contextmanager

我想在python中编写一个临时管理器,暂时禁用全局函数。一般来说这样的事情可以吗?以下是所需行为的示例:

#in module x
def disable_me(): print "do stuff"

#in module y
import x
def run_me():
    print "run_me"
    x.disable_me()

#in module z
import x
import y
with disable_function(x.disable_me):
    y.run_me()

#desired output: run_me

我知道原则上我可以暂时将lambda *args, **kwargs: None分配给x.disable_me,但我不清楚上下文管理器是否有足够的信息来实际执行此操作。

1 个答案:

答案 0 :(得分:3)

这实际上相当容易,只要您不介意传递包含对象和变量的名称,而不是变量本身(这应该不是问题)。

from contextlib import contextmanager

class X:
    def disable_me():
        print("do stuff")

def run_me(x):
    print("run_me")
    x.disable_me()

@contextmanager
def disable_function(obj, name):
    temp = getattr(obj, name)
    setattr(obj, name, lambda: None)
    yield
    setattr(obj, name, temp)

x = X()
with disable_function(x, "disable_me"):
    run_me(x)

这适用于模块和对象,但更容易在这样的文件中显示。