Нелокальный оператор Python в определении класса - PullRequest
9 голосов
/ 29 марта 2011

Я пытаюсь выполнить некоторый анализ области видимости в исходном коде Python 3, и я застрял с тем, как нелокальный оператор оператора работает внутри определения класса.

Насколько я понимаю, определение класса выполняетсяего тело находится в новом пространстве имен (назовите его dict) и связывает имя класса с результатом типа (name, base, 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

Может кто-нибудь объяснить здесь разницу между закрытием определения функции и определения класса?

Ответы [ 2 ]

10 голосов
/ 29 марта 2011

Лексическая область видимости применяется только к пространствам имен функций, в противном случае методы, определенные внутри класса, смогут «видеть» атрибуты уровня класса (то есть, по замыслу - к этим атрибутам вместо этого следует обращаться как к атрибутам self внутри метода).

Те же ограничения, которые приводят к тому, что переменные уровня класса пропускаются ссылками из методов, также не позволяют ключевому слову nonlocal отрабатывать свою магию.(global работает, хотя, поскольку это не зависит от лексического механизма определения объема)

4 голосов
/ 29 марта 2011

Python по-разному обрабатывает определения классов и функций. Например, ваш A.v не является переменной A, а скорее ее атрибутом. Следовательно, пространство имен, созданное классом, не является областью видимости. Я не удивлен, что nonlocal не работает, поскольку вы пытаетесь его использовать.

...