12

Python 3 ソース コードでスコープの分析を実行しようとしていますが、非ローカル ステートメント ステートメントがクラス定義内でどのように機能するかについて悩んでいます。

私が理解しているように、クラス定義はその本体を新しい名前空間内で実行し(dictと呼びます)、クラス名をタイプ(name、bases、dict)の結果にバインドします。非ローカル x は、外側の非ローカル スコープのどこかにバインドされている変数を参照している限り、機能するはずです。

これから、次のコードがコンパイルされて実行されることを期待しています。

class A:
    v = 1
    class B:
        nonlocal v
        v = 2

しかし、これは失敗します

SyntaxError: no binding for nonlocal 'v' found

次のコードは完全に実行されますが

def A():
    v = 1
    class B:
        nonlocal v
        v = 2

関数定義のクロージャとクラス定義の違いを説明できる人はいますか?

4

2 に答える 2

13

レキシカルスコープは関数の名前空間にのみ適用されます。それ以外の場合、クラス内で定義されたメソッドはクラスレベルの属性を「見る」ことができます (これは設計によるものです - これらの属性selfはメソッド内の属性としてアクセスする必要があります)。

クラス レベルの変数がメソッドからの参照によってスキップされるのと同じ制限により、nonlocalキーワードが魔法のように機能しなくなります。(globalただし、レキシカルスコープ機構に依存しないため、機能します)

于 2011-03-29T01:41:58.337 に答える
4

Python は、クラスと関数の定義を異なる方法で処理します。たとえば、 yourA.vは A の変数ではなく、属性です。したがって、クラスによって作成された名前空間はスコープではありません。nonlocalあなたがそれを使おうとしているのに、それがうまくいかなくても、私は驚かない。

于 2011-03-28T23:41:00.787 に答える