在 shell 中和通过脚本执行代码时,选择的字典键/选择的设置值不同

Dict key selected / set value selected are different when code is executed in shell and via script

Python 3.7.4(默认,2020 年 9 月 8 日,19:45:30) linux

上的 [GCC 7.5.0]
first_tuple = (1, 2, )
second_tuple = (1, 2, )
first_list = [1, 2, 3]
second_list = [1, 2, 3]


def main():
    # Question 1
    my_dict = {
        first_tuple: first_list,
        second_tuple: second_list,
    }
    print('dictionary length = {}'.format(len(my_dict)))
    for key in my_dict.keys():
        if id(key) == id(second_tuple):
            print("key selected is 'second_tuple'")
        else:
            print("key selected is 'first_tuple'")
        if id(my_dict[key]) == id(second_list):
            print("value selected is 'second_list'")
        else:
            print("key selected is 'first_list'")
    # Question 2`
    my_set = {first_tuple, second_tuple}
    print('set length = {}'.format(len(my_set)))
    if id(my_set.pop()) == id(second_tuple):
        print("'second_tuple' is considered")
    else:
        print("'first_tuple' is considered")

main()

以上片段在 python shell 中执行时给出的输出为:

dictionary length = 1
key selected is 'first_tuple'
value selected is 'second_list'
set length = 1
'first_tuple' is considered

当同样作为脚本执行时,例如。 python3.7 example.py

dictionary length = 1
key selected is 'second_tuple'
value selected is 'second_list'
set length = 1
'second_tuple' is considered

为什么会有差异?编译器是否在做一些优化?

是的,这是一个编译器优化。编译脚本时,相同的元组用于 first_tuplesecond_tuple。这是允许的,因为元组是不可变的,所以不需要区分相等的元组。

您可以通过一个更简单的示例来了解这一点:

first_tuple = (1, 2, )
second_tuple = (1, 2, )
print(first_tuple is second_tuple)

这会在脚本中打印 True,但在 shell 中打印 False