【问题标题】:`try ... except not` construction`try ... except not` 构造
【发布时间】:2019-09-28 09:24:06
【问题描述】:

最近遇到了一个从未见过的代码示例:

try:
    # a simple bunch of code
    if sample == 0:
        return True
    else:
        raise ExampleError()
except not ExampleError:
    raise AnotherExampleError()

它是如何工作的(如果可以的话)?

【问题讨论】:

  • 你还记得你在哪里遇到这个例子吗?你能和我们分享一下吗?上下文可能会澄清一些事情。是工作代码,还是提案?
  • python2.7 解释器对你的类 ExampleError 执行逻辑 not,其计算结果为布尔值 False,当你将 False 传递给 except 时,它似乎是无操作,否则理论上它将处理用户在 try 块中引发 False 的情况。如果您能够找到一种方法让 python False 扩展异常,这实际上是可能的。我们需要将这个问题升级到 Guido,标题为:“对不起,这他妈的是什么?” Python 鸭子打字再次以惊人的左戳击打。战俘!
  • @EricLeschinski 实际上并不确定,但似乎您只能在 Python 2 中引发 BaseException 或旧式类的子类型。我试图触发它,除了在类中重新定义 __eq__ 块在给出False 时返回True 但它不起作用,但Python 是Python 可能有办法进入该块。

标签: python python-2.7 exception try-catch


【解决方案1】:

编辑:下面的答案是针对 Python 3,我没有意识到与 Python 2.7 相关的问题。在 Python 2 中,如果except 之后的表达式没有产生BaseException 的子类型,解释器不会抱怨。但是,该行为仍然是错误的,它在所有情况下都会忽略 except 块。


这是一个有趣的结构,在语法上有效但在语义上是错误的。我想代码的作者的意思是表达类似“为除ExampleError 之外的任何异常类型运行此except 块”。然而,真正发生的事情更像是:

try:
    # ...
except (not bool(ExampleError)):
    # ...

try 块中引发异常时,Python 会遍历不同的except 块来寻找与异常类型匹配的块。当它看到except not ExampleError,相当于except (not bool(ExampleError))时,它会导致except False,这是无效的,因为False不是BaseException的子类型(或BaseException的子类型的元组)。因此,如果没有引发异常但错误的代码甚至可以运行。

【讨论】:

    【解决方案2】:

    据我所知,这在任何版本的 Python 上都不会成功。因为 not 运算符总是产生一个布尔值(TrueFalse),所以试图在此处捕获其中一个值,在本例中为 False。因为你不能抛出TrueFalse,所以这个没有用。

    我认为作者的意图是这样的:

    try:
        raise ExampleError()
    except ExampleError e:
        throw e
    except:
        raise AnotherExampleError()
    

    【讨论】:

      【解决方案3】:

      快速测试表明,如果代码到达该行,将抛出 TypeError:

      try:
        raise BaseException
      except not BaseException:
        print("Test1")
      except BaseException:
        print("Test2")
      

      例外:

      在处理上述异常的过程中,又发生了一个异常:

      Traceback(最近一次调用最后一次):文件“main.py”,第 3 行,在 除了不是 BaseException:TypeError:不允许捕获不从 BaseException 继承的类

      【讨论】:

      • 如果是这种情况,那么这个问题应该被关闭,因为不可重现。
      • 使用python 3运行代码时会出现上述TypeError,但使用python 2.7运行时不会出现。
      • @Xukrao 我想 2.7 不会对类进行类型检查?所以它是有效的,但实际上并没有做任何事情。
      猜你喜欢
      • 2022-09-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-26
      • 1970-01-01
      • 2013-08-25
      • 1970-01-01
      • 2017-05-14
      • 1970-01-01
      相关资源
      最近更新 更多