Вы устанавливаете локальных переменныеx
в функции setter()
. Назначение имени в функции обозначает его как локальное, если вы специально не укажете компилятору Python в противном случае.
В Python 3, вы можете явно пометить x
как нелокального используя nonlocal
ключевое слово:
def make_adder_and_setter(x):
def setter(n):
nonlocal x
x = n
return (lambda y: x + y, setter)
Теперь x
отмечен в качестве свободной переменной и ищется в окружающем объеме, а не когда назначен.
В Python 2 вы не можете отметьте Python локальным как таковым. Единственный другой вариант, который у вас есть, - это отметка x
как global
. Вам придётся прибегнуть к трюкам, в которых вы изменяете значения, содержащиеся в изменяемом объекте, который живет в окружении.
Атрибут на Функция setter
будет работать, например; setter
является локальным для make_adder_and_setter()
сферы, атрибутов этого объекта будет видны всем, что имеет доступ к setter
:
def make_adder_and_setter(x):
def setter(n):
setter.x = n
setter.x = x
return (lambda y: setter.x + y, setter)
Еще одна хитрости заключается в использовании изменяемого контейнера, например, список:
def make_adder_and_setter(x):
x = [x]
def setter(n):
x[0] = n
return (lambda y: x[0] + y, setter)
В обоих случаях вы: не, назначая местное имя; в первом примере используется назначение атрибутов на объекте setter
, второе изменяет список x
, а не присваивается самому x
.
@Wooble: В конце концов, я потушил. :-) –