Pregunta newbie sobre sockets y urllib2

Gustavo Ces g.ces en pettra.es
Vie Dic 14 08:28:42 CET 2007


> while True: es la forma de decir "repetir una y otra vez hasta que se
> acabe el mundo".

 Esto es lo que me faltaba por entender, creí que estaba relacionado con que 
el try/except fuese tomado como verdadero o falso ( por lo de True), pero 
con esa frase ya he entendido que es un bucle infinito por definición, roto 
por los breaks.

Claro como el agua. Gracias Gabriel :)

Gus

----- Original Message ----- 
From: "Gabriel Genellina" <gagsl-py2 en yahoo.com.ar>
To: <python-es en aditel.org>
Sent: Thursday, December 13, 2007 7:01 PM
Subject: [Python-es] Re: Pregunta newbie sobre sockets y urllib2


> En Thu, 13 Dec 2007 12:17:31 -0300, Gustavo Ces <g.ces en pettra.es> 
> escribi�:
>
>> Saludos,
>>
>>     Gracias por la paciencia. Y tomo nota de tu recomendación. La verdad
>> es
>> que he estado leyendo algo ( no lo suficiente, como puedes comprobar ),
>> pero
>> sólo quería saber cúal sería la forma más correcta. Pero, aún pudiendo
>> equivocarme por ser un poco novato y quedarme en deuda la lectura de
>> toda la
>> información disponible, no había encontrado en la referencia de python
>> sobre
>> Try si el hecho de probar y que no salte una excepción es true y la
>> excepción es false, con lo quedaría claro que tu código sería la opción
>> más
>> sencilla y evidente. En la Guia de Aprendizaje hay un pequeño ejemplo en
>> el
>> que lo usa, en el apartado de Gestion de Excepciones, pero no está muy
>> claro
>> si lo que es True es el hecho de asignar un valor a una variable ( y por
>> lo
>> tanto, ser verdadera) o al hecho de haber salido exitoso el código
>> dentro de
>> try ( si el ejemplo tuviese varias sentencias en el try quedaría mucho
>> más
>> claro).
>
> En el tutorial, el manejo de excepciones está explicado en la seccion 8.2
> No tiene nada que ver con verdadero/falso. Una excepción se genera cuando,
> durante la ejecución del programa, se da una situación que impide que se
> siga ejecutando. Si nunca es atrapada, se terminará mostrando por consola:
>
> py> x = 1
> py> y = 0
> py> z = x/y
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> ZeroDivisionError: integer division or modulo by zero
>
> Para atrapar una excepción, usamos try/except:
>
> py> try:
> ...   z = x/y
> ...   print "cociente=",z
> ... except ZeroDivisionError:
> ...   print "operación imposible"
> ...
> operación imposible
>
> Como la división no se pudo realizar, el flujo normal del programa se
> interrumpe. La sentencia print siguiente no se ejecuta, y el control pasa
> al primer bloque except que tiene una declaración compatible con la
> excepción que fue generada. En este caso, es el único bloque que hay, y se
> imprime "operación imposible".
>
> Volviendo a tu problema: queremos repetir los intentos de conexion a un
> sitio, una y otra vez, hasta que logre conectarse, ok? Qué significa "que
> logre conectarse" en términos pythonescos? Que NO ocurra una excepción del
> tipo IOError. Si ocurre la excepción, hay que seguir intentando. Si no
> ocurre, ya está, nos logramos conectar. Está claro que todo esto hay que
> hacerlo dentro de un bucle, no? Entonces sería algo así:
>
> while True:
>   try:
>     arch = urllib2.urlopen(direccion)
>     break
>   except IOError:
>     pass
>
> while True: es la forma de decir "repetir una y otra vez hasta que se
> acabe el mundo". Dentro del bucle, intentamos conectarnos usando urlopen.
> Si todo anduvo bien, se va a ejecutar la linea siguiente, break. break
> indica "salir del bucle", y es justamente la forma de romper ese bucle
> infinito. En cambio, si hubo un IOError, el break no se va a ejecutar,
> sino que el control va a saltar a la linea pass, que no hace nada. Pero
> seguimos dentro del bucle, asi que vuelta a empezar con el urlopen.
> Aca va una version mejorada:
>
> def urlopen_retry(direccion, reintentos=10, espera=30):
>   i = 0
>   while True:
>     try:
>       arch = urllib2.urlopen(direccion)
>       break
>     except IOError:
>       i += 1
>       if i>reintentos: raise
>       time.sleep(espera)
>   return arch
>
>
> Ahora tiene un cierto numero maximo de reintentos, y un tiempo de espera
> entre cada reintento.
> Lo unico que cambio es la clausula except: si hubo un error, incrementamos
> el numero de reintentos. Si fueron demasiados ya, re-lanzamos la misma
> excepcion (el raise vacío). Es decir, si despues de todos los reintentos
> aún sigue fallando, la excepción le va a llegar a quien haya llamado la
> función. Si simplemente devolviéramos None o algo asi, estaríamos
> descartando mucha información contenida en la excepción que puede ser
> importante para el llamador.
>
> Y ahora solo nos queda el bucle externo, iterando sobre todas las
> direcciones:
>
> for direccion in lista:
>   try:
>     arch = urlopen_retry(direccion)
>   except:
>     print "%s: %s al procesar %s" % (sys.exc_info()[0],
>           sys.exc_info()[1], direccion)
>     continue
>   try:
>     pagina = arch.read()
>   finally:
>     arch.close()
>   html=BeautifulSoup(pagina)
>
> Espero que ahora te quede un poco mas claro.
>
> -- 
> Gabriel Genellina
>
>


--------------------------------------------------------------------------------


_______________________________________________
Lista de correo Python-es
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes 


------------ próxima parte ------------
_______________________________________________
Lista de correo Python-es 
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes


Más información sobre la lista de distribución Python-es