【问题标题】:Why does `if Exception` work in Python为什么`if Exception`在Python中工作
【发布时间】:2014-12-28 22:17:19
【问题描述】:

在这个答案https://stackoverflow.com/a/27680814/3456281 中,提出了以下构造

a=[1,2]
while True:
    if IndexError:
        print ("Stopped.")
        break
    print(a[2])

实际上打印“已停止”。和中断(使用 Python 3.4.1 测试)。

为什么?!为什么if IndexError 甚至是合法的?为什么a[2] 没有提出IndexError 而周围没有try ... except

【问题讨论】:

  • 嗯,这是我的回答,但我没有意识到它总是 True。
  • 这真的很有趣,我从来不知道这个
  • 我删除了答案,因此我被否决了:-)
  • @qqvc 等等...您在建议涉及您不理解的概念的答案?请不要那样做。
  • 我不明白什么?我很清楚这个问题。

标签: python exception exception-handling boolean


【解决方案1】:

所有对象都有一个布尔值。如果没有另外定义,则该布尔值为 True。

所以这段代码就相当于做if True;所以执行会立即到达break 语句,而永远不会到达print

【讨论】:

  • “如果没有另外定义,所有对象都是 True”的来源?
  • @Jasper: docs.python.org/2/reference/datamodel.html#object.__nonzero__ 说“如果一个类既没有定义__len__() 也没有定义__nonzero__(),那么它的所有实例都被认为是真的。”
  • @Jasper: 和Truth Value Testing: 可以测试任何对象的真值,用于ifwhile 条件或作为以下布尔运算的操作数。以下值被认为是假的:[...]所有其他值都被认为是真——所以许多类型的对象总是真。这里的例外只是更多的对象。
  • @MartijnPieters 正确,我要补充一点,通过if object: 测试对象的存在是常见的做法,这意味着对象返回True 是正常行为
  • @MartijnPieters 哼哼,我刚刚意识到这正是你所说的,但以更常见的方式。
【解决方案2】:

查看 Python documentation,Python 标准库的内置类型下的真值测试部分。第一句话和最后一个要点之后的第一句话回答了你的问题。

可以测试任何对象的真值...

所有其他值都被认为是真实的——所以许多类型的对象都是 永远正确。

这是文档的全文,(括号中的内容,[],作为补充添加):

5.1。真值测试

可以测试任何对象的真值,用于 if 或 while 条件或作为以下布尔运算的操作数。以下 值被认为是错误的:

  • None

  • False

  • 任何数字类型的零,例如,00L0.00j

  • 任何空序列,例如,''()[]

  • 任何空映射,例如{}

  • 用户定义类的实例,如果该类定义了__bool__() [__nonzero__() in Python 2] 或__len__() 方法,则该方法返回整数零或布尔值False。 [参见 Python 语言参考的数据模型,特殊方法名称,Basic Customization 部分]

所有其他值都被认为是真实的——所以许多类型的对象都是 永远正确。

始终具有布尔结果的操作和内置函数 返回0False 为假,1True 为真,除非另有说明 表示。 (重要的例外:布尔运算 orand 总是 返回其中一个操作数。)

结论

因此,由于Exception 没有__bool____nonzero____len__,(也不属于上面列出的其他条件)Exception 对象将始终在布尔值中测试为True上下文。

【讨论】:

    猜你喜欢
    • 2020-05-27
    • 1970-01-01
    • 2014-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-16
    相关资源
    最近更新 更多