Message259237
Calling exec() with only one argument is equivalent to exec(..., globals(), locals()). It does not create a new scope for names. So an equivalent of your three-level example is more like
>>> i = 'global'
>>> def f():
... i = 'nonlocal'
... class_locals = dict()
... exec("print(i)\ni = 'local'\nprint(i)\n", globals(), class_locals)
...
>>> f()
global
local
If exec() worked like a function rather than a class, the first print(i) would trigger an UnboundLocalError instead:
>>> i = 'global'
>>> def f():
... i = 'nonlocal'
... def g():
... print(i)
... i = 'local'
... g()
...
>>> f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in f
File "<stdin>", line 4, in g
UnboundLocalError: local variable 'i' referenced before assignment
In your first exec() example, i='nonlocal' is passed to exec() via the default locals parameter, and the exec() uses that value rather than deferring to its globals. To be a free variable, “i” has to be used but not defined. Even if you dropped the “i = 'local' ” assignment, it is still defined via the implicit locals parameter.
Your proposal for “Interaction with dynamic features” sounds reasonable. |
|
Date |
User |
Action |
Args |
2016-01-30 05:14:19 | martin.panter | set | recipients:
+ martin.panter, docs@python, eryksun, abarnert |
2016-01-30 05:14:19 | martin.panter | set | messageid: <1454130859.83.0.483569917515.issue26225@psf.upfronthosting.co.za> |
2016-01-30 05:14:19 | martin.panter | link | issue26225 messages |
2016-01-30 05:14:18 | martin.panter | create | |
|