[英]How to stop statements within a Python with context from executing?
I've some code like this:我有一些这样的代码:
with SomeContext(args):
<statement1>
.
.
<statementN>
I want this code to behave like this:我希望这段代码的行为如下:
if some_condition(args):
f1()
else:
<statement1>
.
.
<statementN>
Statements in else block will also need an access to args. else 块中的语句也需要访问 args。
But I want to hide f1
and some_condition
from user of this abstraction, so using an if-else block is out of option.但是我想对这个抽象的用户隐藏f1
和some_condition
,所以使用 if-else 块是不可行的。 Also I don't want to force a constraint on the user to wrap all statements in a function.此外,我不想强制限制用户将所有语句包装在 function 中。 Is it possible to do some python magic in the with
context that allows this?是否可以在允许这样做with
上下文中做一些 python 魔术?
The closest I can get is to use two nested context managers, something like the following:我能得到的最接近的是使用两个嵌套的上下文管理器,如下所示:
class SkippedException(Exception):
pass
class SkipContext:
def __enter__(self):
pass
def __exit__(self, type, value, tb):
return type is SkippedException
class SomeContext:
def __init__(self, arg):
self.arg = arg
def __enter__(self):
if self.arg == 1:
print "arg", self.arg
raise SkippedException()
def __exit__(self, type, value, tb):
pass
with SkipContext(), SomeContext(1):
print "body"
The SkipContext
manager essentially catches the SkippedException
raised by the inner SomeContext
manager in the case where arg == 1
.在arg == 1
的情况下, SkipContext
管理器基本上捕获了内部SomeContext
管理器引发的SkippedException
。
Note that the syntax of multiple context expressions is only supported in Python 2.7 or later.请注意,仅 Python 2.7 或更高版本支持多个上下文表达式的语法。 In earlier versions, you would have to write:在早期版本中,您必须编写:
with SkipContext():
with SomeContext(1):
print "body"
The contextlib.nested
context manager, despite claims in the documentation, doesn't exactly match the semantics of the above nested with
statement when exceptions are thrown from within __enter__
, so it doesn't work in this case. contextlib.nested
上下文管理器,尽管文档中有声明,但当从__enter__
中抛出异常时,它与上述嵌套with
语句的语义并不完全匹配,因此在这种情况下它不起作用。
It should be noted that PEP 343 mentions that macros (like context managers) that hide flow control should be discouraged, and referencesRaymond Chen's rant against hidden flow control .应该注意的是, PEP 343提到不鼓励隐藏流控制的宏(如上下文管理器),并引用Raymond Chen 对隐藏流控制的咆哮。
Yes, you can easily create such a context manager as follows.是的,您可以轻松地创建这样的上下文管理器,如下所示。
import contextlib
@contextlib.contextmanager
def SomeContext(args):
if some_condition(args):
f1()
else:
yield
The user's wrapped code gets executed at the point of the yield
.用户的包装代码在yield
点执行。 I don't think it's a problem that the context manager sometimes does not execute the user's code, but I haven't checked.我认为上下文管理器有时不执行用户的代码不是问题,但我没有检查过。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.