0

All, When I execute the following code from inside Spyder IDE, I get the same ID of a, b, and the number 1000., yet when I execute the code from the Spyder console, I get different IDs (the ID of a is different from b). Floats are known to be immutable, yet they behave like mutable when executed by the spyder editor. Any idea why this is the case.

a=1000.
b=1000.
print('id of a='+str(id(a)))
print('id of b='+str(id(b)))
print('id of 1.'+str(id(1000.)))

Thanks

S3DEV
  • 8,768
  • 3
  • 31
  • 42
Kernel
  • 591
  • 12
  • 23
  • 1
    It depends on whether the code is compiled as a block or executed line by line. If it's compiled as a single file, equivalent constants will be merged. – Barmar Jun 21 '22 at 16:04
  • @Barmar Even if I executed the code as a block from the console, I get the same result as if I run them line by line. The same also happens with the Spyder Editor. – Kernel Jun 21 '22 at 16:08
  • Which of those is the way that gets different ids? – Barmar Jun 21 '22 at 16:11
  • every time you execute the code, the variables will assigned some memory address. id will return that, every run would be different – Ritwick Jha Jun 21 '22 at 18:26
  • @Barmar when the code is executed from the console – Kernel Jun 21 '22 at 18:56
  • 1
    @RitwickJha The issue isn't that they're different across runs, it's whether all 3 lines in a single run print the same or different id. – Barmar Jun 21 '22 at 18:57
  • @RitwickJha, yes that is right, but what I am saying here is that running the code from the console yields different results for a and b. Yet, running the code from the editor yield the same ID for a and b. – Kernel Jun 21 '22 at 18:57
  • I don't use Spyder -- what's the difference between the Spyder console and the Spyder IDE? – Barmar Jun 21 '22 at 18:58
  • @Barmar for console see https://docs.spyder-ide.org/4/plugins/notebook.html on the bottom right. – Kernel Jun 21 '22 at 19:03
  • @Barmar this is interesting, I think it has to do with the optimizations that occur when using the IDE. when two variables are sharing the same value, their id's are returned to be the same. – Ritwick Jha Jun 21 '22 at 19:04
  • 1
    As I said above, when you run it from the IDE, it's submitting the entire file to Python, which compiles it and performs optimizations. When you use the console it executes each statement separately, to there's no optimization. – Barmar Jun 21 '22 at 19:06
  • @Barmar, it confused me cause we know that floats are immutable, I also execute the three lines as a batch, and I get the same results as if I execute line by line. I did not expect something fundamental like that to vary in such way. Thanks – Kernel Jun 21 '22 at 19:10
  • Forget Spyder for a minute - what is the output in a pure Python (or IPython) terminal. What about if the code is executed while wrapped in a function? – S3DEV Jun 27 '22 at 17:58

1 Answers1

1

This has nothing to do with Spyder, this is purely a Python optimisation, as kindly explained by @Barmar.

Example 1: Line-based execution

When the values are assigned for line-execute (even if the lines are grouped when executed), the following output is provided:

>>> a = 1000.
>>> b = 1000.
>>> print(f'{id(a)=}\n{id(b)=}')

id(a)=140093502852336
id(b)=140093502851184

Different IDs.

Example 2: Function-based execution

However, when the assignments are wrapped in a function (as shown below), Python performs optimisations which basically say: "Hey, I've got a variable for that value already, so I'll just use it again."

def test():
    a = 1000.
    b = 1000.
    print(f'{id(a)=}\n{id(b)=}')

>>> test()
id(a)=140093502851472
id(b)=140093502851472

Same IDs.


Bytecode: Function-based execution

As shown in the bytecode for the test() function, the same ID has been assigned to the variables, due to compiler optimisations.

  2           0 LOAD_CONST               1 (1000.0)  # <-- Here (1)
              2 STORE_FAST               0 (a)

  3           4 LOAD_CONST               1 (1000.0)  # <-- Here (1)
              6 STORE_FAST               1 (b)

  4           8 LOAD_GLOBAL              0 (print)
             10 LOAD_CONST               2 ('id(a)=')
             12 LOAD_GLOBAL              1 (id)
             14 LOAD_FAST                0 (a)
             16 CALL_FUNCTION            1
             18 FORMAT_VALUE             2 (repr)
             20 LOAD_CONST               3 ('\nid(b)=')
             22 LOAD_GLOBAL              1 (id)
             24 LOAD_FAST                1 (b)
             26 CALL_FUNCTION            1
             28 FORMAT_VALUE             2 (repr)
             30 BUILD_STRING             4
             32 CALL_FUNCTION            1
             34 POP_TOP
             36 LOAD_CONST               0 (None)
             38 RETURN_VALUE
S3DEV
  • 8,768
  • 3
  • 31
  • 42
  • Thanks @S3DEV, what about for objects created in code run as a file or cell or inside class definitions? Would that fall under function-based execution too? – user51462 Jul 08 '22 at 05:16