[Python-ideas] Unpack of sequences
Guido van Rossum
guido at python.org
Wed Aug 29 22:44:40 CEST 2012
On Wed, Aug 29, 2012 at 12:30 PM, M.-A. Lemburg <mal at egenix.com> wrote:
> Guido van Rossum wrote:
>> Also it won't work in Python 3.
>
> The star import is only used to trigger a call to PyFrame_LocalsToFast().
>
> In Python 3, the only way to trigger such a call is by using
> a call level trace function... or by exposing the C function
> in Python.
I don't believe that's the whole story. In Python 2, the import *
changes the semantics of locals. (So does 'exec' BTW.) Example:
>>> def f():
... if 0: from test import *
... locals()['x'] = 1
... print(x)
...
<stdin>:1: SyntaxWarning: import * only allowed at module level
>>> def g():
... locals()['x'] = 1
... print(x)
...
>>> f()
1
>>> g()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in g
NameError: global name 'x' is not defined
>>>
Note the difference in generated bytecode:
>>> dis.dis(f)
3 0 LOAD_CONST 1 (1)
3 LOAD_NAME 0 (locals)
6 CALL_FUNCTION 0
9 LOAD_CONST 2 ('x')
12 STORE_SUBSCR
4 13 LOAD_NAME 1 (x)
16 PRINT_ITEM
17 PRINT_NEWLINE
18 LOAD_CONST 0 (None)
21 RETURN_VALUE
>>> dis.dis(g)
2 0 LOAD_CONST 1 (1)
3 LOAD_GLOBAL 0 (locals)
6 CALL_FUNCTION 0
9 LOAD_CONST 2 ('x')
12 STORE_SUBSCR
3 13 LOAD_GLOBAL 1 (x)
16 PRINT_ITEM
17 PRINT_NEWLINE
18 LOAD_CONST 0 (None)
21 RETURN_VALUE
>>>
Compare line 13 in both: LOAD_NAME vs. LOAD_GLOBAL. Effectively, in
f(), the locals are dynamic (this is how they were implemented in
Python 0.0). In g() they are not, so the compiler decides that x can't
be a local, and generates a LOAD_GLOBAL.
In Python 3, all functions behave like g(): import * is no longer
allowed, and exec() is no longer treated special (it's no longer a
reserved keyword).
--
--Guido van Rossum (python.org/~guido)
More information about the Python-ideas
mailing list