Two curious errors when function globals are manipulated
eryk sun
eryksun at gmail.com
Tue Jul 5 12:13:59 EDT 2016
On Tue, Jul 5, 2016 at 3:50 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> It works with exec:
>
> py> from collections import ChainMap
> py> class ChainDict(ChainMap, dict):
> ... pass
> ...
> py> m = ChainDict()
> py> exec("x = 1", m, m)
> py> m['x']
> 1
>
> (Tested in both 3.3 and 3.6.)
No, actually it doesn't work. Remember that when you store to a
variable, it's implicitly a local variable, for which CPython uses
STORE_NAME in unoptimized code. To test this properly you need to
declare the variable as global, so that it uses STORE_GLOBAL:
import dis
from collections import ChainMap
class ChainDict(ChainMap, dict):
pass
m = ChainDict()
code = compile(r'''
global x
x, y = 1, 2
''', '', 'exec')
>>> dis.dis(code)
3 0 LOAD_CONST 3 ((1, 2))
2 UNPACK_SEQUENCE 2
4 STORE_GLOBAL 0 (x)
6 STORE_NAME 1 (y)
8 LOAD_CONST 2 (None)
10 RETURN_VALUE
>>> exec(code, m)
>>> m
ChainDict({'y': 2})
More information about the Python-list
mailing list