关于python:为什么以下代码返回True?

Why does the following code return True?

本问题已经有最佳答案,请猛点这里访问。

我正在做一个任务来编译pascal的一个子集,在初始程序中有一行这样的代码:

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

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

BoolInt的定义如下:

1
2
3
class Int: pass

class Bool: pass

然后,我在该行设置了一个断点,并在vscode的调试器中四处播放:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>> 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


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

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

python对链接比较的评估如下:

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

由于y.tp属于类,因此产生True,实际上在该集合中。

参考比较手册:

Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be False).


当然,我们假设这一行代码

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

应该工作(或分析)如下:

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

但事实并非如此。根据本文,解析和比较的过程如下:

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

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

源:python比较运算符链接