2012-11-30 32 views
2

我有一些这样的代码:如何通过上下文停止Python中的语句执行?

with SomeContext(args): 
    <statement1> 
    . 
    . 
    <statementN> 

我想这段代码的行为是这样的:在else块

if some_condition(args): 
    f1() 
else: 
    <statement1> 
    . 
    . 
    <statementN> 

报表还需要成参数的访问。

但我想隐藏f1some_condition从这个抽象的用户,所以使用if-else块是超出选项。另外我不想强制用户的约束来包装函数中的所有语句。是否可以在with上下文中执行一些python魔术?

回答

2

我能得到的最接近的是使用两个嵌套的上下文管理器,像下面这样:

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" 

SkipContext经理基本上是抓住由内SomeContext经理的情况下提出的,其中arg == 1SkippedException

请注意,多个上下文表达式的语法仅在Python 2.7或更高版本中受支持。在早期版本中,你会写:

with SkipContext(): 
    with SomeContext(1): 
     print "body" 

contextlib.nested上下文管理器,尽管文件要求,不完全匹配上述嵌套with语句的语义异常时,从__enter__内抛出,所以它在这种情况下不起作用。

应该指出,PEP 343提到隐藏流量控制的宏(如上下文管理器)应该不鼓励,并且引用Raymond Chen's rant against hidden flow control

-1

是的,您可以轻松创建如下的上下文管理器。

import contextlib 

@contextlib.contextmanager 
def SomeContext(args): 
    if some_condition(args): 
     f1() 
    else: 
     yield 

用户的包装代码在yield处执行。我不认为这是一个问题,上下文管理器有时不执行用户的代码,但我没有检查。

+0

它不起作用并引发异常。我甚至尝试用一个除了所有例外的包装器包装。然后它抛出一个'AttributeError:__exit__'错误。 –