Evaluación de atributos de clase y generadores.

¿Cómo evalúa Python exactamente los atributos de clase? Me he topado con una peculiaridad interesante (en Python 2.5.2) que me gustaría explicar.

Tengo una clase con algunos atributos que se definen en términos de otros atributos previamente definidos. Cuando intento usar un objeto generador, Python emite un error, pero si uso una comprensión de lista normal, no hay problema.

Aquí está el ejemplo reducido. Tenga en cuenta que la única diferencia es queBrie utiliza una expresión generadora, mientras queCheddar Utiliza una lista de comprensión.

# Using a generator expression as the argument to list() fails
>>> class Brie :
...     base = 2
...     powers = list(base**i for i in xrange(5))
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in Brie
  File "<stdin>", line 3, in <genexpr>
NameError: global name 'base' is not defined

# Using a list comprehension works
>>> class Cheddar :
...     base = 2
...     powers = [base**i for i in xrange(5)]
... 
>>> Cheddar.powers
[1, 2, 4, 8, 16]

# Using a list comprehension as the argument to list() works
>>> class Edam :
...     base = 2
...     powers = list([base**i for i in xrange(5)])
...
>>> Edam.powers
[1, 2, 4, 8, 16]

(Mi caso real fue más complicado, y estaba creando un dict, pero este es el ejemplo mínimo que pude encontrar).

Mi única suposición es que las comprensiones de la lista se calculan en esa línea, pero las expresiones del generador se calculan después del final de la clase, momento en el cual el alcance ha cambiado. Pero no estoy seguro de por qué la expresión del generador no actúa como un cierre y almacena la referencia para basar en el alcance en la línea.

¿Hay alguna razón para esto y, de ser así, cómo debería estar pensando en la mecánica de evaluación de los atributos de clase?

Respuestas a la pregunta(2)

Su respuesta a la pregunta