Namespace puzzle, list comprehension fails within class definition

Steven D'Aprano steve at pearwood.info
Tue Jan 13 05:49:34 CET 2015


On Mon, 12 Jan 2015 12:40:13 -0800, Ethan Furman wrote:

> On 01/12/2015 12:25 PM, John Ladasky wrote:
>> d = {0:"a", 1:"b", 2:"c", 3:"d"}
>> e = [d[x] for x in (0,2)]
>> 
>> class Foo:
>>     f = {0:"a", 1:"b", 2:"c", 3:"d"}
>>     print(f)
>>     g = [f[x] for x in (0,2)]
> 
> In Foo 'f' is part of an unnamed namespace; the list comp 'g' has its
> own namespace, effectively making be a nonlocal; class name lookup skips
> nonlocal namespaces.


Actually, no it doesn't.

py> def factory():
...     x = 23
...     class Inner(object):
...             print('x is', x)
...     return Inner
... 
py> o = factory()
x is 23


The "problem" is that *functions* lookup don't include the class body in 
their scope. This is by design, and goes back to Python 1.5 or older:

[steve at ando ~]$ python1.5
Python 1.5.2 (#1, Aug 27 2012, 09:09:18)  [GCC 4.1.2 20080704 (Red Hat 
4.1.2-52)] on linux2
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> class Outer:
... 	x = 23
... 	f = lambda: x+1
... 	y = f()
... 
Traceback (innermost last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 4, in Outer
  File "<stdin>", line 3, in <lambda>
NameError: x



> Workaround:  use an actual for loop.


Sad but true.



-- 
Steven



More information about the Python-list mailing list