【问题标题】:Why does adding a semicolon in Python change the result? [duplicate]为什么在 Python 中添加分号会改变结果? [复制]
【发布时间】:2019-02-18 12:38:51
【问题描述】:

我发现分号“;”有一个奇怪的行为在 Python 中。

>>> x=20000;y=20000
>>> x is y
True
>>> x=20000
>>> y=20000
>>> x is y
False
>>> x=20000;
>>> y=20000
>>> x is y
False

为什么第一个测试返回“True”,而其他测试返回“False”?我的 Python 版本是 3.6.5。

【问题讨论】:

    标签: python


    【解决方案1】:

    在交互式解释器中,第一个分号行被一次性读取和评估。因此,解释器识别出 20000 是每个赋值中相同的不可变 int 值,因此 可以(它不必,但确实)使 xy 引用到同一个对象。

    重要的一点是,这只是交互式解释器选择进行的优化;语言或; 的某些特殊属性无法保证将两个语句合二为一。

    在以下两个示例中,当 y=20000 被读取和评估时,x=20000(带或不带分号)已经被评估和遗忘。由于 20000 不在预分配的int 值的范围(-5 到 257)内,CPython 不会尝试在内存中查找 20000 的另一个实例;它只是为y 创建一个新的。

    【讨论】:

    • 谢谢,我明白了。然后我也尝试x,y=20000,20000,“x 是 y”也返回 true。所以我认为“x=20000;y=20000”可能会优化为“x,y=20000,20000”。
    • 不是直接的,但同样,因为命令是在一个“批次”输入中,解释器/编译器有更多的机会寻找优化。右侧创建的元组由重复两次的相同文字组成,因此可以使用对同一对象的两个引用来创建元组,而不是分配具有相同值的两个单独对象。
    • 另外,请注意制作解释器的人可以选择让解释器在第二条语句中重用20000 对象;他们只是没有。 (并确保您了解 is== 之间的区别 - 请参阅 Roberto Bonvallet 的回答。)
    • 要了解 为什么 20000 并不总是被重复使用,请考虑让 20000 在您当前正在处理的同一表达式中出现两次与尝试确定文字 20000 是否是在过去的某个任意时间进行评估。第一个只需要查看当前正在评估的表达式;后者需要内存中的专用数据结构来跟踪活动对象。
    【解决方案2】:

    is 运算符检查两个值是否是内存中的同一个对象。它不是用来检查相等性的。值得考虑的是,它有时会返回 True,有时会返回 False,这只是运气问题(即使不是这样)。

    例如,交互式会话和独立程序中的结果不同:

    $ cat test.py
    x = 200000; y = 200000
    print(x is y)
    
    xx = 200000
    yy = 200000
    print(xx is yy)
    
    $ python test.py
    True
    True
    

    或者你还有这个例子:

    >>> x = 50 + 50; y = 50 + 50
    >>> x is y
    True
    >>> x = 5000 + 5000; y = 5000 + 5000
    >>> x is y
    False
    

    发生这种情况是因为解释器缓存了小数字,因此它们始终是同一个对象,但它不适用于大数字,因此在第二种情况下的两个添加都会创建一个新的 10000 对象。它与分号无关。

    【讨论】:

    • 怎么会认为这完全不是运气问题?
    • 什么时候返回 False?
    • @IşıkKaplan 你说得对,事实并非如此。我的意思是,这不是你可以依赖的行为。从某种意义上说,解释器选择Chepner mentioned 的优化是幸运的,而且该示例在交互式控制台中进行了测试(我尝试编写独立程序,结果不同)。
    • @mad_ 我用一个例子扩展了我的答案,其中两个结果相等的表达式用分号分隔使is 运算符返回False
    • 虽然没有不一致,但您可能希望远离不可变的内置插件,不要过多考虑解释器优化,但是对于自定义类,它始终是准确的,并且可以依靠。如果不;我想了解它可以在自定义类中返回错误结果的位置。
    猜你喜欢
    • 2010-09-20
    • 2013-10-02
    • 2021-08-09
    • 2013-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-05
    相关资源
    最近更新 更多