为什么以下代码返回True?

时间:2017-02-19 20:55:08

标签: python python-3.x

我正在做一个编译Pascal子集的任务,在初始程序中有一行代码如下:

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

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

BoolInt的定义如下:

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

2 个答案:

答案 0 :(得分:4)

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

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

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

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

True生成y.tp属于<class 'ST.Int'>类并且实际上在该集合中。

来自Reference Manual on Comparisons

  

比较可以任意链接,例如,x < y <= z等同于x < y and y <= z,但y仅评估一次(但在两种情况下z都未评估所有x < y被发现为False时。

答案 1 :(得分:0)

当然,我们假设这行代码

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

应该像以下一样工作(或解析):

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

但这是的情况。根据{{​​3}},解析然后比较完成如下:

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

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

来源:this article