See this previous question, which is similar but not identical.
As stated in that answer:
classes don't have a lexical scope (actually, in either Python 2 or Python 3). Instead, they have a local namespace that does not constitute a scope. This means that expressions within the class definition have access to the content of the namespace [...] but scopes introduced within the body of the class do not have access to its namespace
In a generator expression, the for
clause is in the enclosing scope/namespace, but the target expression is in a new scope created by the generator expression. This new scope doesn't have access to the enclosing class scope.
In short, your examples work and fail for the same reason that this works:
class Foo(object):
a = 2
def method(self, x=a):
print x
but this fails:
class Foo(object):
a = 2
def method(self, x):
print a
The for
clause of the generator expression is similar scopewise to the argument specification of a method: it executes in the enclosing namespace. But the target expression of the genexp is similar to the method body: it executes in its own scope, which does not have access to the class namespace.
(In Python 2, using a list comprehension instead of a generator comprehension will work because list comprehensions do not createa new scope in Python 2. This was considered a wart and was changed in Python 3, so in Python 3 neither one will work.)