Почему нелокальное ключевое слово «прерывается» глобальным ключевым словом?

#python #scope

#python #область видимости

Вопрос:

Я начинающий программист, пытающийся изучить python, и я столкнулся с темой областей видимости. Я столкнулся с ошибкой «не найдено привязки для нелокального var_name» при выполнении самого нижнего кода. Может кто-нибудь объяснить, почему нелокальное ключевое слово не может «смотреть мимо» промежуточной функции во внешнюю функцию?

 
#this works
globe = 5


def outer():
    globe = 10
    def intermediate():

        def inner():
            nonlocal globe
            globe = 20
            print(globe)
        inner()
        print(globe)
    intermediate()
    print(globe)


outer()
  
 
globe = 5


def outer():
    globe = 10
    def intermediate():
        global globe #but not when I do this
        globe = 15
        def inner():
            nonlocal globe #I want this globe to reference 10, the value in outer()
            globe = 20
            print(globe)
        inner()
        print(globe)
    intermediate()
    print(globe)


outer()
  

Ответ №1:

Выражения, включающие nonlocal ключевое слово, заставят Python пытаться найти переменную во вложенных локальных областях, пока она не встретит первое указанное имя переменной.

nonlocal globe Выражение будет выглядеть, если в функции есть переменная с именем globe intermediate . Однако он столкнется с ним в global области видимости, поэтому он будет предполагать, что он достиг области модуля и завершил его поиск, не найдя ни nonclocal одного, отсюда и исключение.

Объявив global globe в intermediate функции, вы в значительной степени закрыли путь для доступа к любым nonlocal переменным с тем же именем в предыдущих областях. Вы можете взглянуть на обсуждение здесь, почему было «решено» реализовать этот способ в Python.

Если вы хотите убедиться, что переменная globe находится или не находится в локальной области действия какой-либо функции, вы можете использовать dir() функции, потому что из документов Python:

Без аргументов верните список имен в текущей локальной области. С помощью аргумента попытайтесь вернуть список допустимых атрибутов для этого объекта.

Комментарии:

1. Хотя, честно nonlocal говоря, документы ( docs.python.org/3/reference/simple_stmts.html#nonlocal ) упомяните это The nonlocal statement causes the listed identifiers to refer to previously bound variables in the nearest enclosing scope excluding globals. , так что в соответствии с этим глобальные переменные следует игнорировать, но, похоже, это не так.