Уведомления

Группа в Telegram: @pythonsu

#1 Апрель 11, 2010 13:51:50

krwlr
От:
Зарегистрирован: 2007-01-15
Сообщения: 26
Репутация: +  0  -
Профиль   Отправить e-mail  

lambda в цикле, обработка исключений.

Всем доброго дня! Прошу помощи так как возникла маленькая проблема, а как решить пока не знаю.
Начну с кода:

import socket
impor urllib2

socket.setdefaulttimeout(0) # Провоцируем вызов ошибки

for line in array:
try:
connect_to_host = lambda get_request : urllib2.urlopen(get_request).read()

content = connect_to_host(line)

...

except urllib2.URLError, errmsg:
print(line, errmsg)
connect_to_host(line)
Но обрабатывается ошибка только один раз, потом при вызове connect_to_host(line.strip()) - выбивает исключение.
Нужен совет, как это побороть!? То есть чтоб повторно обрабатывалось исключение.. :)



Офлайн

#2 Апрель 11, 2010 14:49:33

Zubchick
От:
Зарегистрирован: 2009-07-08
Сообщения: 613
Репутация: +  0  -
Профиль   Отправить e-mail  

lambda в цикле, обработка исключений.

вы объявили функцию connect_to_host в теле try, а вызываете и в except



Офлайн

#3 Апрель 11, 2010 15:18:37

krwlr
От:
Зарегистрирован: 2007-01-15
Сообщения: 26
Репутация: +  0  -
Профиль   Отправить e-mail  

lambda в цикле, обработка исключений.

Эммм… не совсем вас поняла. Из except'a нельзя вызвать функцию объявленную в блоке try? Может я неправильно вас поняла.
Просто нужно чтоб при возникновении ошибки, функция вызвалась с тем же параметром. Т.е. передаётся запрос на сервер, если истекает тайм-аут, вызывается исключение и вновь создаем соединение с хостом, но с той же строкой, что не удалась. Не хочется выносить подключение в отдельную функцию, важна скорость.. даже полторы минуты разницы :)


P.S. пробовала переписать код на ruby - работает, но функция не видна вне блока {}, кошерно вызывается redo.
Вроде на руби и проще, и скорость программы выше (за счет регулярных выражений), но … нужно решить на питоне.



Отредактировано (Апрель 11, 2010 15:24:15)

Офлайн

#4 Апрель 11, 2010 15:49:21

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

lambda в цикле, обработка исключений.

Непонятно зачем вообще вам эта лямбда, честно говоря.
Я может не понял идею, но вот так исключение будет перехвачено в каждый раз:

import socket
import urllib2

socket.setdefaulttimeout(0)

for line in ("http://google.com", "http://ya.ru"):
for i in (1,2):
try:
content = urllib2.urlopen(line).read()
break
except urllib2.URLError, errmsg:
print(">>>", line, errmsg)



Офлайн

#5 Апрель 11, 2010 16:20:48

krwlr
От:
Зарегистрирован: 2007-01-15
Сообщения: 26
Репутация: +  0  -
Профиль   Отправить e-mail  

lambda в цикле, обработка исключений.

Потому что по истечению тайм-аута, мне нужно повторить запрос пока он не будет положительным.
Суть в том, чтоб не ждать долгого ответа от сервера, подключились, создали запрос, таймаут? - повторили этот же запрос, обработали его и дальше по списку..



Офлайн

#6 Апрель 11, 2010 17:10:33

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

lambda в цикле, обработка исключений.

Ну и причем здесь лямбда? Если хотите повторять запрос бесконечно, пока он не выполнится, то вместо for i in (1,2) используйте бесконечный цикл.



Офлайн

#7 Апрель 11, 2010 17:34:44

krwlr
От:
Зарегистрирован: 2007-01-15
Сообщения: 26
Репутация: +  0  -
Профиль   Отправить e-mail  

lambda в цикле, обработка исключений.

Я удивляюсь и вами и собой)) Особенно, собой.. неужели я так плохо объясняю!? :)
Вы меня не поняли, for i in (1,2) - это перебор элемента из массива и с последующей отправкой его (элемента серверу). Так вот, если возникло исключение, то нужно повторно отправить на сервер ЭТОТ элемент массива. Не просто перехватить ошибку, сообщить и пойти дальше, оставив этот элемент просто так..
Фуф, выдохнула..)



Офлайн

#8 Апрель 11, 2010 17:46:02

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

lambda в цикле, обработка исключений.

Вы объясняете действительно не очень. Давайте по порядку разбираться. В вашем изначальном коде было 2 вызова вашей лямбды. Поэтому я сделал вам пример с двумя повторениями запроса и усомнился попутно в нужности лямбды. Потом вы написали, что хотите бесконечно повторять запросы, пока они не будут положительными. Я посоветовал изменить цикл на бесконечный. Вы мой код пробовали?
for i in (1,2) - это не то, что вы думаете, а просто повторение одного и того же запроса 2 раза. Если посмотреть внимательно, то будет видно, что i внутри цикла не используется.



Офлайн

#9 Апрель 11, 2010 18:09:41

krwlr
От:
Зарегистрирован: 2007-01-15
Сообщения: 26
Репутация: +  0  -
Профиль   Отправить e-mail  

lambda в цикле, обработка исключений.

Ed, спасибо вам за терпение :)

Итак, насчет: for i in (1,2) - Да, заговорилась, имела в виду свой цикл for line in array.
Насчет for i in (1,2) - запрос постоянно два раза повторять не нужно. Его повторить нужно лишь в случае, если возникла ошибка URLError.

Ed
Потом вы написали, что хотите бесконечно повторять запросы, пока они не будут положительными.
Если возникла ошибка - обрабатываем и вызываем снова функцию соединения с хостом с повторной отправкой неудавшегося сообщения. Если вновь ошибка возникла - опять обрабатываем, опять передаём, и так по кругу.. Но, очень важно: тот элемент который не удалось отправить. Не следующий. Для этих целей я использовала повторный вызов lambda-функции из except'a. Но он обрабатывается раз. И всё.(((



Офлайн

#10 Апрель 11, 2010 18:15:24

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

lambda в цикле, обработка исключений.

krwlr
Его повторить нужно лишь в случае, если возникла ошибка URLError.
Он и не повторяется. Обратите внимание на break. Он обеспечивает выход из цикла повторения, если исключения не произошло.

Кстати, если запросы у вас идут к разным сайтам я бы посоветовал слегка изменить алгоритм. Не долбить один сайт, а переходить сразу к другому и только когда весь список перебрали опять пытаться послать запрос этому сайту. И бесконечное количество попыток - это тоже не очень хорошо. Я бы все таки ограничился каким-то конечным количеством.



Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version