Области переменных внутри определений классов сбивают с толку - PullRequest
0 голосов
/ 23 декабря 2018

По некоторым причинам python получает переменную из глобального пространства имен при возникновении подобных ситуаций:

class Cls:
    foo = foo

Пожалуйста, посмотрите на этот код:

foo = 'global'

def func0():
    foo = 'local'
    class Cls:
        bar = foo
    print('func0', Cls.bar)
 func0()
 # func0 local

def func1():
    foo = 'local'
    class Cls:
        foo = foo
    print('func1', Cls.foo)
func1()
# func1 global

def func2():
    foo = 'nonlocal'
    def internal():
        class Cls:
            foo = foo
        print('func2.internal', Cls.foo)
    internal()
func2()
# func2.internal global

def func3():
    foo = 'local'
    class Cls:
        bar = foo
        foo = foo
    print('func3', Cls.bar, Cls.foo)
func3()
# func3 global global

В соответствии с PEP 227

Определение класса - это исполняемый оператор, который может содержать использования и определения имен.Эти ссылки следуют обычным правилам разрешения имен.Пространство имен определения класса становится словарем атрибутов класса.

, но для меня это совсем не похоже на "следование нормальным правилам".Чего мне не хватает?

И Py2, и Py3 работают таким образом.

1 Ответ

0 голосов
/ 23 декабря 2018

Это задокументировано в Модель исполнения - Разрешение имен :

Блоки определения класса [...] являются специальными в контексте разрешения имен.Определение класса - это исполняемый оператор, который может использовать и определять имена.Эти ссылки следуют обычным правилам разрешения имен, за исключением того, что несвязанные локальные переменные ищутся в глобальном пространстве имен.

(выделено мной)

...