#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.
, так что в соответствии с этим глобальные переменные следует игнорировать, но, похоже, это не так.