I think that I know how variables and generators work in Python well.
However, the following code makes me confused.
from __future__ import print_functio
As stated in other answer, it is True that it happens because it is static variable. But it is not just that property that restricts your code to work. Actual reason is the scope of the variable and the scope in which it executes. For example, create a class as:
class A(object):
x = 999999
y = x +1
If you access it's class properties A.x and A.y, it will work. Because, at the time of initializing y, x is replaced the value in expression x+1. As the scope of x was within the class.
However this doesn't happens in the case of generators. i.e. in your example:
class A(object):
x = 4
gen = (x for _ in range(3))
When you do list(a.gen), it is executed outside the class (as generators are evaluated during run-time) and checks for the reference of x in the current scope. Since, x it is not initialized in that scope, it throws error.
When you explicitly initialize x=4, it works because now the generator expression has value of x to which it could use.
In order to make your generator expression work, as stated by others you have to define it like:
class A(object):
x = 4
gen = (A.x for _ in range(3))
# ^ mentioning `A.x` is the value to access
Because x is a class attribute (static variable), which you access like,
Example
>>> class A(object):
... x = 4
... gen = (A.x for _ in range(3))
...
>>> a = A()
>>> list(a.gen)
[4, 4, 4]
Here even gen is another class attribute, which means that,
>>> b = A()
>>> list(b.gen)
[]
This gives empty because the generator has already exhausted.
a.gen, when it won't be able to resolve the name x.
That is because x is a class variable. In python, class variables has to be accessed with self (ex. access from a instance method) or the class name.
class A(object):
x = 4
gen = (A.x for _ in range(3))
def call_me(self):
print self.x
a = A()
a.call_me()
print list(a.gen)
For more detailed discussion see Static class variables in Python and Why is Python class not recognizing static variable