Ocena atrybutów klasy i generatory

Jak dokładnie Python ocenia atrybuty klasy? Natknąłem się na ciekawy dziwak (w Pythonie 2.5.2), który chciałbym wyjaśnić.

Mam klasę z pewnymi atrybutami, które są zdefiniowane w kategoriach innych, wcześniej zdefiniowanych atrybutów. Kiedy próbuję użyć obiektu generatora, Python zgłasza błąd, ale jeśli używam zwykłego zwykłego rozumienia listy, nie ma problemu.

Oto przykład skrócony. Zauważ, że jedyną różnicą jest toBrie używa wyrażenia generatora, podczas gdyCheddar używa rozumienia listy.

# 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]

(Moja rzeczywista sprawa była bardziej skomplikowana i tworzyłem dyktat, ale jest to minimalny przykład, jaki mogłem znaleźć.)

Domyślam się, że wyrażenia listy są obliczane w tej linii, ale wyrażenia generatora są obliczane po zakończeniu klasy, w którym to momencie zakres się zmienił. Ale nie jestem pewien, dlaczego wyrażenie generatora nie działa jako zamknięcie i przechowuje odniesienie do bazy w zakresie na linii.

Czy jest ku temu powód, a jeśli tak, to jak powinienem myśleć o mechanice oceny atrybutów klasowych?

questionAnswers(2)

yourAnswerToTheQuestion