Найти - Пользователи
Полная версия: Помогите понять код
Начало » Центр помощи » Помогите понять код
1 2
Leron
Такая вот штука:
>>> 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
???
Александр Кошелев
Лист это ссылка со всеми вытекающими.
ZAN
Если более подробно, то в первом случае переменная для функции inc является глобальной. Запись вида curr += 1 вызаывает в области видимости функции inc ранее созданный объект. Во втором же случае происходит переопределение переменной curr вызовом curr += 1.
Что происходит дальше, читать здесь -> http://www.python.org/dev/peps/pep-0227/.
А происходит вот что - переопределение переменной говорит интерпретатору о том, что в области видмиости пременная является локальной, но для вызова curr += 1, локальная переменная уже должна хранить значение, чего в действиетльности нет - об этом сообщает нам соответствующий Exception.
ZAN
Вот еще один примерчик для понимания:
>>> 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
Если существует локальная переменная, то функция будет видеть только ее, поэтому попытка вывести значение глобальной переменной терпит неудачу (второй случай)
Leron
Спасибо, я почитал 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.
hellt
а можно еще раз пояснить, почему cur = start не является глобальной переменной для inc()?
ZAN
В действительности, во втором случае существуют две одноименные переменные, но внутри функции она не видна, т.к. просмотрев функцию, и заметив в ней присвоение, интерпретатор воспринимает curr только как локальную.
hellt
почему тогда curr += 1 , что эквивалентно curr = curr + 1 —- не попадает по рамки "я нашел присвоение и значит curr ищется локально"?

sry, не могу врубится(
ZAN
Потому, как, я уже писал (об этом еще упоминал Daevaorn), в случае со списком происходит не переопределение переменной, а ее модификация. В данном случае - инкрементация компонента списка с нулевым индексом.
Yurietc
Если нужно в блоке изменить глобальную переменную, нужно использовать инструкцию global.
>>> def counter1(start):
	global curr
        curr = start
        def inc():
		global curr
                curr += 1
                return curr
        return inc
>>> f2 = counter(4)
>>> f2()
5
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB