Форум сайта python.su
Такая вот штука:
>>> def counter(start):
curr =
def inc():
curr += 1
return curr
return inc
>>> f1 = counter(4)
>>>
>>> f1()
5
>>> f1()
6
Непонятно почему нужно использовать лист а такой код вызывает ошибку:
>>> def counter1(start):
curr = start
def inc():
curr += 1
return curr
return inc
>>> f2 = counter1(4)
>>> f2()
Traceback (most recent call last):
File “<pyshell#42>”, line 1, in <module>
f2()
File “<pyshell#40>”, line 4, in inc
curr += 1
UnboundLocalError: local variable ‘curr’ referenced before assignment
???
Отредактировано (Май 30, 2008 14:46:15)
Офлайн
Лист это ссылка со всеми вытекающими.
Офлайн
Если более подробно, то в первом случае переменная для функции inc является глобальной. Запись вида curr += 1 вызаывает в области видимости функции inc ранее созданный объект. Во втором же случае происходит переопределение переменной curr вызовом curr += 1.
Что происходит дальше, читать здесь -> http://www.python.org/dev/peps/pep-0227/.
А происходит вот что - переопределение переменной говорит интерпретатору о том, что в области видмиости пременная является локальной, но для вызова curr += 1, локальная переменная уже должна хранить значение, чего в действиетльности нет - об этом сообщает нам соответствующий Exception.
Офлайн
Вот еще один примерчик для понимания:
>>> a = 1
>>> def inc():
print a
>>> inc()
1
>>> a = 1
>>> def inc():
print a
a = 2
>>> inc()
Traceback (most recent call last):
File “<pyshell#27>”, line 1, in -toplevel-
inc()
File “<pyshell#26>”, line 2, in inc
print a
UnboundLocalError: local variable ‘a’ referenced before assignment
Если существует локальная переменная, то функция будет видеть только ее, поэтому попытка вывести значение глобальной переменной терпит неудачу (второй случай)
Отредактировано (Май 30, 2008 15:33:05)
Офлайн
Спасибо, я почитал pep вроде разобралсо:
Jeremy Hylton
If a name is used within a code block, but it is not bound there
and is not declared global, the use is treated as a reference to
the nearest enclosing function region. <> If they(binding operations ) occur within a block, they introduce new local names in the
current block unless there is also a global declaration.
Офлайн
а можно еще раз пояснить, почему cur = start не является глобальной переменной для inc()?
Офлайн
В действительности, во втором случае существуют две одноименные переменные, но внутри функции она не видна, т.к. просмотрев функцию, и заметив в ней присвоение, интерпретатор воспринимает curr только как локальную.
Офлайн
почему тогда curr += 1 , что эквивалентно curr = curr + 1 —- не попадает по рамки "я нашел присвоение и значит curr ищется локально"?
sry, не могу врубится(
Офлайн
Потому, как, я уже писал (об этом еще упоминал Daevaorn), в случае со списком происходит не переопределение переменной, а ее модификация. В данном случае - инкрементация компонента списка с нулевым индексом.
Офлайн
Если нужно в блоке изменить глобальную переменную, нужно использовать инструкцию global.
>>> def counter1(start): global curr curr = start def inc(): global curr curr += 1 return curr return inc >>> f2 = counter(4) >>> f2() 5
Офлайн