Уведомления

Группа в Telegram: @pythonsu

#1 Май 30, 2008 14:43:16

Leron
От:
Зарегистрирован: 2007-12-11
Сообщения: 59
Репутация: +  0  -
Профиль   Отправить e-mail  

Помогите понять код

Такая вот штука:
>>> 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)

Офлайн

#2 Май 30, 2008 15:06:39

Александр Кошелев
От: Москва
Зарегистрирован: 2007-02-03
Сообщения: 1724
Репутация: +  2  -
Профиль   Отправить e-mail  

Помогите понять код

Лист это ссылка со всеми вытекающими.



Офлайн

#3 Май 30, 2008 15:26:26

ZAN
От:
Зарегистрирован: 2007-06-10
Сообщения: 403
Репутация: +  10  -
Профиль   Отправить e-mail  

Помогите понять код

Если более подробно, то в первом случае переменная для функции inc является глобальной. Запись вида curr += 1 вызаывает в области видимости функции inc ранее созданный объект. Во втором же случае происходит переопределение переменной curr вызовом curr += 1.
Что происходит дальше, читать здесь -> http://www.python.org/dev/peps/pep-0227/.
А происходит вот что - переопределение переменной говорит интерпретатору о том, что в области видмиости пременная является локальной, но для вызова curr += 1, локальная переменная уже должна хранить значение, чего в действиетльности нет - об этом сообщает нам соответствующий Exception.



Офлайн

#4 Май 30, 2008 15:32:21

ZAN
От:
Зарегистрирован: 2007-06-10
Сообщения: 403
Репутация: +  10  -
Профиль   Отправить e-mail  

Помогите понять код

Вот еще один примерчик для понимания:
>>> 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)

Офлайн

#5 Май 30, 2008 16:24:06

Leron
От:
Зарегистрирован: 2007-12-11
Сообщения: 59
Репутация: +  0  -
Профиль   Отправить e-mail  

Помогите понять код

Спасибо, я почитал 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.



Офлайн

#6 Май 30, 2008 16:40:39

hellt
От:
Зарегистрирован: 2008-03-14
Сообщения: 45
Репутация: +  0  -
Профиль   Отправить e-mail  

Помогите понять код

а можно еще раз пояснить, почему cur = start не является глобальной переменной для inc()?



Офлайн

#7 Май 30, 2008 17:03:58

ZAN
От:
Зарегистрирован: 2007-06-10
Сообщения: 403
Репутация: +  10  -
Профиль   Отправить e-mail  

Помогите понять код

В действительности, во втором случае существуют две одноименные переменные, но внутри функции она не видна, т.к. просмотрев функцию, и заметив в ней присвоение, интерпретатор воспринимает curr только как локальную.



Офлайн

#8 Май 30, 2008 17:38:06

hellt
От:
Зарегистрирован: 2008-03-14
Сообщения: 45
Репутация: +  0  -
Профиль   Отправить e-mail  

Помогите понять код

почему тогда curr += 1 , что эквивалентно curr = curr + 1 —- не попадает по рамки "я нашел присвоение и значит curr ищется локально"?

sry, не могу врубится(



Офлайн

#9 Май 30, 2008 20:36:01

ZAN
От:
Зарегистрирован: 2007-06-10
Сообщения: 403
Репутация: +  10  -
Профиль   Отправить e-mail  

Помогите понять код

Потому, как, я уже писал (об этом еще упоминал Daevaorn), в случае со списком происходит не переопределение переменной, а ее модификация. В данном случае - инкрементация компонента списка с нулевым индексом.



Офлайн

#10 Май 31, 2008 16:36:10

Yurietc
От:
Зарегистрирован: 2007-07-18
Сообщения: 112
Репутация: +  0  -
Профиль   Отправить e-mail  

Помогите понять код

Если нужно в блоке изменить глобальную переменную, нужно использовать инструкцию global.

>>> def counter1(start):
	global curr
        curr = start
        def inc():
		global curr
                curr += 1
                return curr
        return inc
>>> f2 = counter(4)
>>> f2()
5



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version