【问题标题】:Conditionally skipping the body of Python With statement [duplicate]有条件地跳过 Python With 语句的主体 [重复]
【发布时间】:2020-03-05 10:17:39
【问题描述】:

我有一个 With 声明,如果对某些 <condition> 感到满意,我想跳过它。也就是说,我写:

With MyContext() as mc:
  do_something()

class MyContext(object):
...
def __enter__(self,...):
  if <condition>:
    JumpToExit()
def __exit__(self,...):
  print('goodbye')

我希望 do_something() 仅在特定条件下执行,否则我希望 JumpToExit() 完全跳过正文并完成块。

谢谢。

【问题讨论】:

标签: python python-3.x


【解决方案1】:

这是不可能的。 with 语句不能取消块。但是,您可以这样做:

def __enter__(self):
    return condition

那么,当你使用上下文时:

with context as condition:
    if condition:
        ....

如果你还想返回其他东西,你可以返回一个像 return condition, self 这样的元组,然后使用它你可以解压像 with condition, context: 这样的元组。

【讨论】:

    【解决方案2】:

    我不确定这是否可能。 __enter__with 语句引入的try 块之外执行,所以我看不到直接从__enter__ 跳转到__exit__ 的方法。

    with 基本上(简化)变成了这个:

    with context as x:
        do_something()
    

    进入

    x = context.__enter__()
    try:
        do_something()
    finally:
        context.__exit__()
    

    您需要在do_something() 中抛出异常或成功完成它才能进入__exit__。如果你确实从do_something() 抛出异常,你可以做一些棘手的事情,比如在 exit 函数中抑制它(使用传递给它的一些参数),所以你实际上看不到它。但它必须是 with 块内的代码以某种方式导致跳转到 __exit__

    也许如果你可以通过在__enter__ 中设置一些值来确保do_something 立即抛出异常,你就可以让它工作。但这对我来说听起来不是一个好主意。

    【讨论】:

      【解决方案3】:

      您可以将 with 语句放在函数中并使用 return:

      def foo():
          With MyContext() as mc:
              if <condition>:
                  return None
              do_something()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多