[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