new*_*123 7 python contextmanager
正如标题所述,有没有办法做到这样的事情:
def call_back():
if called inside context:
print("running in context")
else:
print("called outside context")
Run Code Online (Sandbox Code Playgroud)
这将导致:
with CTM() as context:
call_back()
call_back()
>>> "running in context"
>>> "called outside context"
Run Code Online (Sandbox Code Playgroud)
正如@chepner 在问题评论中所写
inspect我认为,如果不使用该模块,就不可能。context.__enter__除了保证在执行之前和context.__exit__之后调用之外,with 语句中的代码块没有什么特别之处。
然后@larsks 建议,如果你可以控制上下文管理器......
...您可以更新一些全局或特定于对象的状态来指示您是否位于上下文管理器内。
这似乎是@new-dev-123最终采用的解决方案。
在这里你有这个解决方案:
class CTM:
def __init__(self):
self._is_in_context = False
def __enter__(self):
self._is_in_context = True
return self
def __exit__(self, *args, **kwargs):
self._is_in_context = False
def call_back(self):
if self._is_in_context:
print("running in context")
else:
print("called outside context")
Run Code Online (Sandbox Code Playgroud)
>>> with CTM() as context:
... context.call_back()
running in context
>>> context.call_back()
called outside context
Run Code Online (Sandbox Code Playgroud)
如果您希望多个方法具有相同的行为,或者将职责分开,则可以使用装饰器。
def reveal_context(func):
def inner(self, *args, **kwargs):
if self._is_in_context:
print("running in context")
else:
print("called outside context")
return func(self, *args, **kwargs)
return inner
class CTM:
def __init__(self):
self._is_in_context = False
def __enter__(self):
self._is_in_context = True
return self
def __exit__(self, *args, **kwargs):
self._is_in_context = False
@reveal_context
def call_back(self):
pass
Run Code Online (Sandbox Code Playgroud)