Этот вопрос является продолжением вопроса об области видимости переменных Python . Дополнительные вопросы q1 , q2 и , ответы , среди прочего, можно найти на SO. Официальная документация Python , и PEP 3104 должны объяснять детали, но мне они не кажутся полностью самоочевидными.
Тема, которую я пытаюсь решить, - это рефакторинг кода, содержащего нелокальный
/ глобальный
, путем перемещения этого кода вверх / вниз на один уровень иерархии.
Я не понимаю значения этого предложения из справочника Python:
Имена, перечисленные в нелокальном операторе, в отличие от имен, перечисленных в глобальном операторе , должны относиться к ранее существовавшим привязкам во включающей области (область, в которой должна быть создана новая привязка, не может быть определена однозначно).
Учитывая следующий код в глобальной области видимости:
var = 0
def outer():
global var # line A
var = 1
def inner():
nonlocal var # line B
var = 2
print('inner:', var)
inner()
print('outer:', var)
outer()
print('main:', var)
Выполнение вызывает ошибку:
SyntaxError: no binding for nonlocal 'var' found
Код работает (конечно, с другой семантикой, если любая строка A закомментирована:
inner: 2
outer: 2
main: 0
или строка B закомментирована:
inner: 2
outer: 1
main: 1
Однако в приведенном выше примере, и поскольку предполагается, что нелокальный
связывает var с «охватывающей областью», я ожидал, что строка A связывает внешний / var с затем глобальная область видимости и строка B ищет внешний / var, а также повторно связывает внутренний / var с глобальным / var. Вместо этого он, кажется, не находит его вообще (из-за повторного связывания в строке A, я полагаю) и вызывает ошибку.
Желаемый результат, которого я ожидал, был:
inner: 2
outer: 2
main: 2
Это просто еще один пример сбивающего с толку состояния области видимости в Python?
Или, чтобы сделать это конструктивным вопросом:
глобальный
на нелокальный
и наоборот)? external ()
изменить код, который не должен иметь ни внешний (в данном случае глобальный) уровень, ни уровень inner ()
быть тронутым? - В моем скромном понимании языка таких конструкций (зависимостей от замыканий) просто следует избегать. Другие уже предлагали использовать другие языковые функции ( классы , func attrs ) для достижения такой контекстной чувствительности.