【问题标题】:Ignore with statement body?忽略语句体?
【发布时间】:2019-09-15 01:56:01
【问题描述】:
class Test:
    def __init__(self):
        pass

    def __enter__(self):
        pass

    def __exit__(self, exc_type, exc_val, exc_tb):
        pass


with Test():
    print (1) # any way to ignore it?

有没有办法忽略(不执行)with 语句体?

也就是说,在这种情况下,我不想执行 print (1)(但我不想将此表达式包装在函数中等)

我在一个个人实验项目中需要这个。

尝试了一些选项,例如抛出异常,但似乎不起作用。

PS: 我不能在任何结构中包装with body(至少在调用 Test 类之前)。 我想在Test类里面实现这个,比如调用一个类的时候,一些monkeypatch可能会起作用等等。

PS2:忽略 with body 后程序应该仍然可以工作

【问题讨论】:

  • 您不能将另一个布尔变量与if 语句一起使用吗?
  • 你想完成什么?
  • 我想忽略 with 正文中的所有表达式。剩下的就很长了。简而言之,我想尝试将 with 语句用作装饰器之类的东西。
  • 似乎是这样。泰萨尔
  • 为了节省您的时间,直接进入 Python3 版本:stackoverflow.com/a/54765496/5754797

标签: python


【解决方案1】:
from contextlib import suppress

class Pass(Exception):
    ...

class _skip:
    def __enter__(self):
        raise Pass

    def __exit__(self, exc_type, exc_val, exc_tb):
        pass

suppress = suppress(Pass)
skip = _skip()

with suppress, skip:
    print('ABC')
    raise SyntaxError
    print('XYZ')

print('Hello World')

您可能不完全喜欢with suppress, skip: 语法,但我非常相信它们可以封装到一个管理器中,只是我懒得做,这似乎已经足够好了。

【讨论】:

  • 这是一个有趣的解决方案,它甚至不使用sys.settrace。这可能对我的情况有用,是的,我不想在with 行中有suppress,在这种情况下,如果没有一些硬技巧,这似乎是无法避免的......我认为这是唯一的时刻这使我无法接受这个答案。
  • 是的,我认为您可以使用contextlib.ExitStack 重写py2 中的contextlib.nested,但从未想过_skip 实际上不是一个合适的上下文管理器。话虽如此,是的,我认为没有黑客就不可能将它们组合起来。我不太喜欢使用像sys.settrace 这样完全依赖于运行时的代码,尽管如果你不介意的话,我可以尝试在其中加入一些魔法,然后像with skip: 那样做。虽然显然有人已经为你链接了一些适用于这种黑客的东西。
  • 如果你的意思是使用 settrace 破解它,我想我不需要它,因为有这个解决方案 stackoverflow.com/a/54765496/8324477
【解决方案2】:

您可以只使用 if False 语句来包装您不想执行的内容,如下所示:

class Test:
    def __init__(self):
        print('>>', 'init')
        pass

    def __enter__(self):
        print('>>', 'enter with')
        pass

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('>>', 'exit with')
        pass


with Test():
    if False:  # will never run this block
        print (1) 

运行结果:

>> init
>> enter with
>> exit with

【讨论】:

  • 抱歉不准确,我已经补充了这个问题。我不能用任何结构包裹身体
猜你喜欢
  • 1970-01-01
  • 2015-11-27
  • 2021-11-15
  • 2017-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-28
相关资源
最近更新 更多