Найти - Пользователи
Полная версия: lambda в цикле, обработка исключений.
Начало » Python для новичков » lambda в цикле, обработка исключений.
1 2
krwlr
Всем доброго дня! Прошу помощи так как возникла маленькая проблема, а как решить пока не знаю.
Начну с кода:
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()) - выбивает исключение.
Нужен совет, как это побороть!? То есть чтоб повторно обрабатывалось исключение.. :)
Zubchick
вы объявили функцию connect_to_host в теле try, а вызываете и в except
krwlr
Эммм… не совсем вас поняла. Из except'a нельзя вызвать функцию объявленную в блоке try? Может я неправильно вас поняла.
Просто нужно чтоб при возникновении ошибки, функция вызвалась с тем же параметром. Т.е. передаётся запрос на сервер, если истекает тайм-аут, вызывается исключение и вновь создаем соединение с хостом, но с той же строкой, что не удалась. Не хочется выносить подключение в отдельную функцию, важна скорость.. даже полторы минуты разницы :)


P.S. пробовала переписать код на ruby - работает, но функция не видна вне блока {}, кошерно вызывается redo.
Вроде на руби и проще, и скорость программы выше (за счет регулярных выражений), но … нужно решить на питоне.
Ed
Непонятно зачем вообще вам эта лямбда, честно говоря.
Я может не понял идею, но вот так исключение будет перехвачено в каждый раз:
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)
krwlr
Потому что по истечению тайм-аута, мне нужно повторить запрос пока он не будет положительным.
Суть в том, чтоб не ждать долгого ответа от сервера, подключились, создали запрос, таймаут? - повторили этот же запрос, обработали его и дальше по списку..
Ed
Ну и причем здесь лямбда? Если хотите повторять запрос бесконечно, пока он не выполнится, то вместо for i in (1,2) используйте бесконечный цикл.
krwlr
Я удивляюсь и вами и собой)) Особенно, собой.. неужели я так плохо объясняю!? :)
Вы меня не поняли, for i in (1,2) - это перебор элемента из массива и с последующей отправкой его (элемента серверу). Так вот, если возникло исключение, то нужно повторно отправить на сервер ЭТОТ элемент массива. Не просто перехватить ошибку, сообщить и пойти дальше, оставив этот элемент просто так..
Фуф, выдохнула..)
Ed
Вы объясняете действительно не очень. Давайте по порядку разбираться. В вашем изначальном коде было 2 вызова вашей лямбды. Поэтому я сделал вам пример с двумя повторениями запроса и усомнился попутно в нужности лямбды. Потом вы написали, что хотите бесконечно повторять запросы, пока они не будут положительными. Я посоветовал изменить цикл на бесконечный. Вы мой код пробовали?
for i in (1,2) - это не то, что вы думаете, а просто повторение одного и того же запроса 2 раза. Если посмотреть внимательно, то будет видно, что i внутри цикла не используется.
krwlr
Ed, спасибо вам за терпение :)

Итак, насчет: for i in (1,2) - Да, заговорилась, имела в виду свой цикл for line in array.
Насчет for i in (1,2) - запрос постоянно два раза повторять не нужно. Его повторить нужно лишь в случае, если возникла ошибка URLError.
Ed
Потом вы написали, что хотите бесконечно повторять запросы, пока они не будут положительными.
Если возникла ошибка - обрабатываем и вызываем снова функцию соединения с хостом с повторной отправкой неудавшегося сообщения. Если вновь ошибка возникла - опять обрабатываем, опять передаём, и так по кругу.. Но, очень важно: тот элемент который не удалось отправить. Не следующий. Для этих целей я использовала повторный вызов lambda-функции из except'a. Но он обрабатывается раз. И всё.(((
Ed
krwlr
Его повторить нужно лишь в случае, если возникла ошибка URLError.
Он и не повторяется. Обратите внимание на break. Он обеспечивает выход из цикла повторения, если исключения не произошло.

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