不一致性“是”在Python 3.6的行为了不可变对象和老年人VS 3.7

问题描述 投票:3回答:4

我被介绍是运营商给我的学生时,我注意到,在Python(3.6版以上)和(3.7版)之间的行为不一致。

启动一个Python shell并运行:

5/2 is 2.5

要么:

(1, 2, 3) is (1, 2, 3)

在v3.6.X你False两个,但在V3.7他们练得True

我的期望是,结果应该是真实的,因为我以为不可改变的数字对象(或它们的元组)只有一个实例。

看来,至少我的想法是不正确的Python的早期版本。

有谁知道已经进行了什么样的变化,说明此项新的行为?

python python-3.x internals
4个回答
5
投票

我不知道原因和来源,这一点,但我的猜测是,这已经是与在线优化。

如果你将这个值赋给变量,身份检查将导致False,和以前一样。

>>> 5/2 is 2.5
True
>>> a = 5/2
>>> a is 2.5
False

新的折叠优化有趣的说明。由于蟒蛇是“所有运行时”,有没有办法提前优化了一些东西,但它力图,解析尽可能多的范围,因为它可以:

>>> a = 3.14
>>> b = 3.14
>>> a is b
False
>>> a = 3.14; b = 3.14
>>> a is b
True

2
投票

我的期望是,结果应该是真实的,因为我以为不可改变的数字对象(或它们的元组)只有一个实例。

这种期望是值得怀疑的 - 有由Python语言保证没有这样的事情。

is是一个相当棘手的操作,因为你真的需要知道什么时候适合使用它。

例如:

>>> 5 / 2 is 2.5
>>> (1, 2, 3) is (1, 2, 3)

这些都不是在一般情况下is适当的用途。如果要检查什么线/功能优化(实习)Python是做什么,但我想这是不期望的用例在这里,他们可能是合适的。

如果你想比较常数(即,保证只有一个实例)is,才应使用!该guaranteed built-in constants是:

  • None
  • NotImplemented
  • Ellipsis(也称为...
  • True
  • False
  • __debug__

或者你自己定像实例:

_sentinel = object()

def func(a=_sentinel):
    return a is _sentinel

或者当你明确指定变量为一个新名称:

a = b
a is b  # <- that's expected to be True

有谁知道已经进行了什么样的变化,说明此项新的行为?

也许窥视孔优化现在更优化的情况下(元组和数学表达式)。例如,“AST-级别的常量折叠”(https://bugs.python.org/issue29469)已在CPython的3.7加(我故意写的CPython这里,因为它是已被添加到了Python 3.7语言规范没有)。


2
投票

我认为,这种行为是由于移动从窥孔优化的常数合并(编译时运转)向新的AST优化器(运行时操作),这是它在https://docs.python.org/3/whatsnew/3.7.html#optimizations也提到现在能够更稳定地进行优化。 (在bpo-29469bpo-11549供稿尤金Toder和INADA直树。)

Re:

我的期望是,结果应该是真实的,因为我以为不可改变的数字对象(或它们的元组)只有一个实例。

不变性是不严格相同,具有不可改变的值。你调用一个对象可变或不可变之前,它是在Python对象和对象是在运行时创建的。因此没有理由可变性连接对象的创建和身份。有,但是,有一些例外象在,主要用于优化的缘故,这条规则(对象创建在运行时)被操纵两个以前和当前版本实习这一个或小物件。阅读https://stackoverflow.com/a/38189759/2867928了解更多详情。


1
投票

为什么要不可改变的是相同占据相同的实例对象?

当使用Python is,你基本上是问ab占用内存中的同一块。如果你觉得ab作为不可改变的文字的,它不是像Python有一个特定的空间来保存所有类型的不可变的文字的。这是纯粹的机会,它在这种情况下返回真实,完全有可能的,如果你选择一个不同的文字也将返回false。看看this

>>> a = "wtf"
>>> b = "wtf"
>>> a is b
True

>>> a = "wtf!"
>>> b = "wtf!"
>>> a is b
False

>>> a, b = "wtf!", "wtf!"
>>> a is b
True

如果你想避免这种情况,不要的东西,你没有明确地保存到内存使用is

© www.soinside.com 2019 - 2024. All rights reserved.