【问题标题】:Why does the following code return True? [duplicate]为什么下面的代码返回 True? [复制]
【发布时间】:2017-07-09 00:51:19
【问题描述】:

我正在做一个编译 Pascal 子集的作业,在初始程序中有这样一行代码:

if x.tp == y.tp in {Bool, Int}:
    some other code ...

这让我很困惑,因为x.tp == y.tp 返回一个布尔值True 或False,因此True/False in {Bool, Int} 将始终返回False。

Bool和Int的定义如下:

class Int: pass

class Bool: pass

然后,我在该行设置一个断点,并在 VSCode 的调试器中运行:

>> x.tp
<class 'ST.Int'>
>> y.tp
<class 'ST.Int'>
>> x.tp == y.tp
True
>> a = (x.tp == y.tp)
None
>> a
True
>> a in {Bool, Int}
False
>> x.tp == y.tp in {Bool, Int}
True       <----------------------- why does it return True?

为什么x.tp == y.tp in {Bool, Int} 在这里返回True?

【问题讨论】:

  • x.tp 和 y.tp 是什么?
  • @JimFasarakis-Hilliard x.tp 和 y.tp 都是类型。我不确定是否应该发布更多代码,因为它太长了

标签: python python-3.x


【解决方案1】:

当然,我们假设这行代码

if x.tp == y.tp in {Bool, Int}:

应该像这样工作(或解析):

if (x.tp == y.tp) in {Bool, Int}:

但情况不是。根据this article,解析然后比较是这样完成的:

if (x.tp == y.tp) and (y.tp in {Bool, Int}) :

由于不明确,有些事情令人困惑。为了代码维护者的利益,请尽量避免类似情况。

来源:Python comparison operators chaining

【讨论】:

  • 实际上,如果你这样做 True in {bool} 你会得到 False。
  • @Jackddddd 更新了解释!
【解决方案2】:

使用括号对相等比较进行分组:

if (x.tp == y.tp) in {Bool, Int}:

您的链式比较被 Python 评估为:

if x.tp == y.tp and y.tp in {Bool, Int}:

产生True,因为y.tp 属于&lt;class 'ST.Int'&gt; 类,并且实际上在该集合中。

来自Reference Manual on Comparisons:

比较可以任意链接,例如,x &lt; y &lt;= z 等价于 x &lt; y and y &lt;= z,除了 y 只被评估一次(但在这两种情况下,z 根本不被评估,当 x &lt; y 被发现时是False)。

【讨论】:

  • 这不重要,因为 == 和 in 具有相同的优先级,它会从左到右进行评估,不是吗?
  • @Jackddddd == 被评估,y.tp in {Bool, Int} 也被评估(因为相等性是 True)并使得整个事情 True,这就是 Python 处理链式比较的方式。
猜你喜欢
  • 2021-11-10
  • 2014-12-20
  • 2015-06-22
  • 2013-07-28
  • 2015-10-07
  • 1970-01-01
  • 2019-02-08
  • 1970-01-01
  • 2015-05-06
相关资源
最近更新 更多