4

私はしたい:

class Whatevs(object):
    foo = 3
    bar = foo * 3

    def __init__(self):
        # enhance!

またはどのように私は正しく働くことを可能にすることができますか。;)

編集:

わかりました、それは問題ではないことがわかりました、しかし、上記はうまくいきます:

class Whatevs(object):
    foo = 3
    zap = list(foo for _ in range(10))

ああ、Python!私はいくつかの回避策を思い付くことができますが、誰かが私に何が起こっているのかを正確に説明できますか?ジェネレータがクラス変数にアクセスできないのはなぜですか?

4

3 に答える 3

4

ジェネレータ内包表記は、実際にはジェネレータを明示的に定義するための省略形です。舞台裏であなたが書こうとしているものは以下と同等です:

class Whatevs(object):
    foo = 3
    def _gen():
        for _ in range(10):
            yield foo
    zap = list(_gen())

foo残念ながら、ジェネレーター内やクラス本体で定義された関数などからスコープ変数にアクセスすることはできません (まだ存在しないWhatevs.fooため使用できWhatevsません。

1 つのオプションは、コードをクラス本体の外に移動することです。

class Whatevs(object):
    foo = 3

Whatevs.zap = list(Whatevs.foo for _ in range(10))

別のオプションは、foo をパラメーターに変換することです。

def _init_zap(foo):
    return list(foo for _ in range(10))

class Whatevs(object):
    foo = 3
    zaps = _init_zap(foo)

Python 2.xa ではリスト内包表記がここで機能しますが、Python 3.x での変更の 1 つは、リスト内包表記もジェネレーター内包表記と同様に別のスコープ (つまり、隠し関数) を使用することでした。したがって、リスト内包表記は Python 3 でも壊れます。 .

于 2013-02-13T15:04:39.760 に答える
1

あなたは試すことができます:

class Whatevs(object):
    foo = 3
    zap = [foo] * 10

あるいは:

class Whatevs(object):
    foo = 3
    zap = [foo for _ in range(10)]

その理由は、Python のクラスには独自の名前空間があるためです。この名前空間に導入されたスコープは、この名前空間にアクセスできません。したがって、ジェネレーター式のスコープから、Whatevs' 名前空間内の変数にアクセスできません。

私のリスト内包表記は新しいスコープを導入していません - 少なくとも Python 2.x では。Python 3.x ではこれが変更されたため、オプション 2 も機能しません。

于 2013-02-13T14:51:51.753 に答える