Python: Different results when using PyCharm and IDLE/python

那年仲夏 提交于 2019-12-01 15:51:01
Tadhg McDonald-Jensen

This is because of how LOAD_CONST byte code works:

Pushes co_consts[consti] onto the stack.

Since integers are stored as constants then assignments to the same integer in the same context will yield the exact same result, we can see that the arguement to LOAD_CONST is 0 for both a and b:

>>> import dis
>>> dis.dis("a = 1000 ; b = 1000")     
  1           0 LOAD_CONST               0 (1000)
              3 STORE_NAME               0 (a)
              6 LOAD_CONST               0 (1000)
              9 STORE_NAME               1 (b)
             12 LOAD_CONST               1 (None)
             15 RETURN_VALUE
                                       # ^ this is the argument 

where as in an interactive session each command is compiled separately (so that they can be executed separately) so the constants will be different:

>>> code1 = compile("a = 1000","<dummy file>","exec")
>>> code2 = compile("a = 1000","<dummy file>","exec")
>>> code1.co_consts, code2.co_consts
((1000, None), (1000, None))
>>> code1.co_consts[0] is code2.co_consts[0]
False

Similarly the constant in a function will always be the same but it will be different to the constant in other functions:

def f():
    return 1000
def g():
    return 1000 #different code object!!

#these all work
assert f() is f()
assert g() is g()
assert f() is not g()
assert f() is not 1000 and g() is not 1000

Also note that as @AniMenon has pointed out the numbers from -5 to 256 are singletons for optimization so the same will not hold true for numbers in that range.

From the documentation for the is operator:

The operators is and is not test for object identity: x is y is true if and only if x and y are the same object.

Now lets check IDLE:

>>> a = 1000
>>> b = 1000
>>> print ( a is b )
False
>>> 
>>> 
>>> id(a)
35334812
>>> id(b)
35334800

PyCharm:

>>> a = 1000
b = 1000
print (a is b)
True
>>> id(a)
36079236
>>> id(b)
36079236

In PyCharm both a and b are the same objects when in IDLE they are not.

Now what's instersting in PyCharm, that if you entering your code line by line, like in IDLE, you'll get the same results as in IDLE:

>>> a = 1000
>>> b = 1000
>>> print (a is b)
False

My guess, that

>>> a = 1000
    b = 1000

is optimized to:

>>> a = b = 1000
>>> print (a is b)
True

So that's why you got same object for a and b

Ani Menon

is will return True if two variables point to the same object, == will return True if the objects referred to by the variables are equal.

In python,

>>> a = [1, 2, 3]
>>> b = a
>>> b is a 
True
>>> b == a
True

>>> b = a[:]
>>> b is a
False
>>> b == a
True

That's because we are matching the id(a) to id(b).

Consider,

a = 1000
b = 1000
a is b

a is b would be False; your assumptions about identity only hold in CPython for numbers in the range -5 to 256 inclusive, which are singletons for performance reasons, but all other ints are recreated as needed, not singletons.

Based on : reference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!