Cong Ma <[email protected]> added the comment:
> sum(get(i) for i in range(len(l)))
This expression inside the body of ``func()`` references the name "get" and "l"
(ell), both are local to the scope introduced by ``func()``. More specifically,
these two names are referenced in the unnamed inner scope introduced by the
generator-expression ``(get(i) for i in range(len(l)))``. It's as if you've
passed into that inner scope the locals already introduced in func() by
argument passing, e.g.
```
def func(...):
get = ...
ell = ...
def genexpr(a, b):
return <expression using a and b>
sum(genexpr(get, ell))
```
> eval("get(0) + get(1) + get(2) + get(3)")
The expression in the string doesn't introduce its own scope. The name "get" is
resolved because without additional arguments, eval() gets the locals from the
calling scope's locals, which is where the name "get" came.
> eval("sum(get(i) for i in range(len(l)))", locals())
This tells eval() to use the calling scope's locals (the value returned by the
call ``locals()``) as the globals for the evaluation of the expression in the
string. When eval() executes the compiled code, it's as if that piece of code
lives in an environment where names like "gets" and "l" (ell) are top-level.
Therefore these names are resolved.
> eval("sum(get(i) for i in range(len(l)))")
Without explicitly telling eval() which globals/locals namespaces to use,
eval() uses the current calling scope's. This is as if it were called like
eval("sum(get(i) for i in range(len(l)))", globals(), locals())
A problem arises. The generator expression in the string introduces an
anonymous inner scope (let's call that scope "the box"). Inside the box, the
name "i" is a local, there's no problem. But for the name "get", it's not local
to the box, and it's not a global. Unlike other kinds of enclosed scope (for
example, one introduced by an inner ``def`` block), "the box" has no way to
look up names in enclosing scopes. This is the limitation referred to by the
Language Reference's section on dynamic execution.
These are my attempts to explain why something works while others don't, based
on my own understanding. I hope this helps somewhat, and if I made a mistake
anywhere please correct them.
----------
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue43605>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com