Name resolution and the (wrong?) LEGB rule

Peter Otten __peter__ at web.de
Thu Dec 8 13:03:38 EST 2016


Chris Angelico wrote:

> On Fri, Dec 9, 2016 at 1:51 AM, Marco Buttu <marco.buttu at gmail.com> wrote:
>> "if a particular name:object mapping cannot be found in the local
>> namespaces, the namespaces of the enclosed scope are being searched next.
>> If the search in the enclosed scope is unsuccessful, too, Python moves on
>> to the global namespace, and eventually, it will search the built-in
>> namespace (side note: if a name cannot found in any of the namespaces, a
>> NameError will is raised)."
>>
>> AFAIK, Python has static scoping: the scope for a name is given during
>> the bytecode compilation. This means that before executing the program,
>> Python already know in which namespace to look for an object. So, it
>> seems to me that the LEGB rule is wrong,

It might be sufficient to say that the LE part is usually statically 
determined while the GB part is dynamic. 

The odd beast is the class namespace:
 
>>> x = "outer"
>>> class C:
...     print(x)
...     x = "inner"
...     print(x)
...     del x
...     print(x)
... 
outer
inner
outer

> It isn't wrong, but there are some parts of it that can be resolved at
> compile time. Once a function is compiled, it cannot normally gain or
> lose local names. There are a few situations that can mess with that
> (a star import or 'exec' statement, in Python 2), and when the
> compiler detects one of those, it has to avoid the usual optimization.
> 
> The "usual optimization" is exactly what you describe: that different
> bytecodes represent Local, Enclosing, and Global/Built-in scope
> lookups. (Globals can be created or removed at run-time, so there's no
> optimization possible there.) But in terms of language specifications,
> the lookup rules are the same; it's just that the CPython compiler
> takes advantage of information that it can see ("these are the only
> locals for this function") to speed up execution.

If it is only an optimization why doesn't a failing local lookup fall back 
to the global namespace?



More information about the Python-list mailing list