[Edu-sig] source code from SA:10648

Tim Peters tim.peters at gmail.com
Tue Jul 20 03:55:27 CEST 2010


[kirby urner]
> ... here's another basic
> question.  Is there a way, after importing from __future__,
> to revert to the "old ways" later on in the same script?
> ...
> I'm not saying this would ever be a good idea, just
> wondering about possibilities...

In general it's not possible.  At least CPython compiles an entire
file into bytecode before anything is executed.  That's why __future__
imports have to be the first non-trivial statements in a file:  they
can change just about anything, including the bytecode that gets
generated.

For example, here's a little program:

def f():
    print x / y

import dis
dis.dis(f)

That defines a tiny function, then displays the bytecode generated:

  2           0 LOAD_GLOBAL              0 (x)
              3 LOAD_GLOBAL              1 (y)
              6 BINARY_DIVIDE
              7 PRINT_ITEM
              8 PRINT_NEWLINE
              9 LOAD_CONST               0 (None)
             12 RETURN_VALUE

It's not necessary to know what any of those mean, although they
should be pretty obvious ;-)  If you change the program by putting:

from __future__ import division

at the top, the output changes:

  4           0 LOAD_GLOBAL              0 (x)
              3 LOAD_GLOBAL              1 (y)
              6 BINARY_TRUE_DIVIDE
              7 PRINT_ITEM
              8 PRINT_NEWLINE
              9 LOAD_CONST               0 (None)
             12 RETURN_VALUE

Note that the third operation changed, from BINARY_DIVIDE to BINARY_TRUE_DIVIDE.

This is all done before anything in the file is executed, so after
execution begins it's too late to change any of it:  the opcode will
remain whatever was generated at the start (BINARY_DIVIDE or
BINARY_TRUE_DIVIDE) no matter what you do while the program is
running.  After all, the instant after you import the future, it
becomes the past, and nobody can change the past ;-)


More information about the Edu-sig mailing list