I would like to write a context manager in python that temporarily disables a function globally. Is such a thing possible to do generically? Here is an example of the desired behavior:

#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

I know that, in principle, I can temporarily assign lambda *args, **kwargs: None to x.disable_me but it's not clear to me if the context manager has enough information to actually do this.

有帮助吗?

解决方案

This is actually reasonably easy to do, provided you don't mind passing the containing object and the name of the variable, rather than the variable itself (which shouldn't be an issue).

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)

This will work with modules as well as objects, but it's easier to show in one file like this.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top