如何检测 Python 中 ContextManager 的使用情况?

问题描述 投票:0回答:1

我正在尝试重构以下内容:

with MyContext() as ctx:
    ctx.some_function()

...更像这样:

with MyContext():
    some_function()

如何在

some_function
的主体中检测到我在
MyContext()
的上下文中调用了它?我更希望这是以线程安全的方式完成的。

这似乎是可能的,因为它是在内置

decimal
模块中完成的:

from decimal import localcontext

with localcontext() as ctx:
    ctx.prec = 42   # Perform a high precision calculation
    s = calculate_something()
python refactoring contextmanager
1个回答
0
投票

听起来你想爬上调用堆栈, 寻找上下文管理器的证据。

#! /usr/bin/env python

from io import StringIO
import dis
import inspect


class MyManager:
    def __enter__(self) -> None:
        print("enter")

    def __exit__(self, exc_type, exc_value, traceback) -> None:
        print("exit")


def app() -> None:
    with MyManager() as m:
        report_on_ctx_mgr()


def report_on_ctx_mgr() -> None:
    stack = inspect.stack()
    assert "app" == stack[1].function
    fn = globals()[stack[1].function]
    src = inspect.getsource(fn)
    print(list(filter(_contains_with, src.splitlines())))

    out = StringIO()
    dis.dis(fn, file=out)
    disasm = out.getvalue()
    if "MyManager" in disasm:
        print(disasm)


def _contains_with(s: str) -> bool:
    return "with " in s


if __name__ == "__main__":
    app()

输出:

['    with MyManager() as m:']
 16           0 RESUME                   0

 17           2 LOAD_GLOBAL              1 (NULL + MyManager)
...
© www.soinside.com 2019 - 2024. All rights reserved.