reference - Why does Python handle '1 is 1**2' differently from '1000 is 10**3'? -


Inspired by the question about caching of small integers and cables, I came to know the following behavior that I did not understand:

<> & gt; & Gt; & Gt; 1000 is 10 ** 3 wrong

I thought I understand this behavior: 1000 is big for being cached. 1000 and 10 ** 2 different objects from point 3 but I was wrong:

  & gt; & Gt; & Gt; 1000 1000 is true  

So, maybe Python calculates different from 'normal' integers. But this assumption is also not correct:

  & gt; & Gt; & Gt; 1 This is 1 ** 2 true  

How can this behavior be explained?

Here are two different things: Python Store int liters (and others) Literals) Compiled bytecocon with and , the small integer objects are cached in the form of singletons.

When you run 1000 1000 , only one constant is stored and reused. You are actually viewing the same object:

  & gt; & Gt; & Gt; Import vs & gt; & Gt; & Gt; Collect ('1000 is 1000', 'end lie; stdin', 'eval'). Co_consts (1000,) & gt; & Gt; & Gt; Dis.dis ('1000 1000,' 'lt; stdin & gt;', 'eval')) 0 0 LOAD_CONST 0 (1000) 3 LOAD_CONST 0 (1000) 6 COMPARE_OP 8 (is) 9 RETURN_VALUE  

here LOAD_CONST refers to the constant at index 0; You can see the constraint stored in the attribute of the .co_consts bytecode object.

Compare it to 1000 10 ** 3 case:

  & gt; & Gt; & Gt; Collection ('1000 10 ** 3', 'and lieutenant; stdin & gt;', 'eval'). Co-Conquest (1000, 10, 3, 1000) & gt; & Gt; & Gt; Dis.dis (compile ('1000 10, 3,', ',' eval ')) 1 0 LOAD_CONST 0 (1000) 3 LOAD_CONST 3 (1000) 6 COMPARE_OP 8 (is) 9 RETURN_VALUE  

is a Peephol customization, which pre-counts expressions on constants at compile time, and this customization 10 ** 3 to 1000 , but the optimization does not reuse pre-existing constants. As a result, LOAD_CONST opodes are loading two separate integer objects on index 0 and 3, And these two different int are objects.

Then there are customizations on that place; During the lifetime of a Python program, only a copy of the object has been made of 1 ; It applies to all integers between 5 and 256.

Thus, 1 for 1 ** 2 is the case, Python Internal uses a singleton int Object from internal cache There is a CPython implementation description.

The ethics of this story is that you should never use is when you want to compare the value to the integer == Use, always.


Comments