我正在做一个编译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
?
答案 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