Pythonはどのようにクラス属性を正確に評価しますか?私は、私が説明したいと思う面白い変種(Python 2.5.2)を見つけました。クラス属性評価とジェネレータ
私は、他の定義済みの属性に関して定義されたいくつかの属性を持つクラスを持っています。ジェネレータオブジェクトを使用しようとすると、Pythonはエラーを投げますが、通常の普通のリスト理解を使用すると問題はありません。
ここでは例を示します。唯一の違いは、Cheddar
はリストの理解度を使用しているのに対し、Brie
はジェネレータ式を使用することです。
# 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]
(私の実際のケースが複雑だった、と私は辞書を作成していたが、これは私が見つけることができる最小の一例です。)
私の唯一の推測では、リストの内包表記は、その行で計算されていることですただし、ジェネレータの式は、スコープが変更されたクラスの終了後に計算されます。しかし、なぜジェネレータの式がクロージャとして動作しないか分からず、ラインのスコープ内にベースへの参照を格納しています。
これには理由がありますか?その場合、クラス属性の評価の仕組みをどのように考える必要がありますか?