El gran libro de Python. Marco Buttu

Чтение книги онлайн.

Читать онлайн книгу El gran libro de Python - Marco Buttu страница 22

Автор:
Серия:
Издательство:
El gran libro de Python - Marco Buttu

Скачать книгу

      La gestión de las excepciones

      En esta sección presentamos el mecanismo de gestión de las excepciones. Para ello, consideremos el archivo myfile.py:

image

      Si lo ejecutamos y escribimos una cadena de texto que no puede ser convertida a entero, la función integrada int() detecta una excepción de tipo ValueError:

image

      Podemos gestionar la excepción insertando entre las palabras clave try y except la línea lógica que da lugar al error. Este se gestionará en el bloque de código que sigue a la palabra clave except:

image image

      La palabra clave try es una instrucción compuesta y except es una cláusula única. Cuando son ejecutadas las instrucciones de la suite del try, si no surge ningún error, la ejecución pasa directamente de la última instrucción del bloque try a la instrucción siguiente a la try/except, omitiendo por tanto la suite de la except. En cambio, si una línea lógica en la suite del try detecta una excepción, la ejecución desde dicha línea pasa directamente a la cláusula except. Esta comprueba que el tipo de la excepción detectada corresponda al que se trata de gestionar, en cuyo caso se ejecuta su suite para poder gestionar el error; en caso contrario, la suite except se omite.

      En nuestro caso, la except gestiona solo las excepciones de tipo ValueError. Por tanto, si escribimos un número que genera un IndexError cuando se intenta indexar la lista, esta excepción no será gestionada:

image

      Si se desean gestionar los dos tipos de excepciones en la misma cláusula except, es posible insertar los tipos ValueError e IndexError en una tupla, del modo siguiente:

image image

      También es posible separar la gestión de los distintos tipos de excepción en diferentes cláusulas except:

image

      Acabamos esta sección diciendo que, si en la cláusula except no se especifica ningún tipo de excepción, se capturarán las excepciones de todos los tipos:

image image

      No debemos utilizar esta modalidad solo por pereza, porque, si lo que hace nuestro código no está absolutamente claro, hay muchas probabilidades de que perdamos el tiempo en vez de ganarlo. Y esto porque en la except no se muestra ningún mensaje de error, por lo que, si se comprobaran los errores que no tenemos previstos, no conseguiríamos entender los motivos del mal funcionamiento. Además, estos errores imprevistos serían gestionados del mismo modo que aquellos que sí hemos previsto gestionar en la except, aunque quizás habrían debido ser gestionados de manera separada. Esto en el mejor de los casos, porque, por la ley de Murphy, nuestra pereza normalmente será la causa de errores lógicos difíciles de detectar y localizar.

      En el Capítulo 5 hablaremos en detalle de las excepciones y, entre otras cosas, veremos como el mecanismo de la herencia nos permite capturar de manera apropiada todas las excepciones, dejando que se propaguen aquellas que no representan errores.

      Los argumentos tratados en esta sección pueden no resultar del todo claros, por lo que si lo encontramos difícil, no nos desesperemos: podremos regresar a dichos argumentos en otra ocasión, una vez hayamos adquirido un poco más de soltura con el lenguaje.

      El protocolo de iteración

      El protocolo de iteración se describe en la PEP-0234. Este define el comportamiento que debe tener un objeto contenedor para que puedar iterarse en él, por ejemplo, en un bucle for, para obtener sus elementos uno a uno. El protocolo se basa en un objeto denominado iterador, el cual dispone de los siguientes métodos:

      • iterator._ _iter_ _(): es un método del objeto que devuelve una referencia al mismo objeto;

      • iterator._ _next_ _(): es un método que devuelve el elemento siguiente del contenedor, o bien detecta una excepción de tipo StopIteration si los elementos del contenedor han sido todos devueltos.

      Un objeto contenedor obj se considera iterable si es posible acceder a sus elementos mediante indexación, o bien si cuenta con un método obj._ _iter_ _() que devuelve un iterador.

      Según estas definiciones, un iterador es un objeto iterable, mientras que un objeto iterable no se considera que sea un iterador. Por ejemplo, un conjunto no es un iterador porque no tiene el método set._ _next_ _():

image

      Veamos si es un objeto iterable. En primer lugar, comprobamos que tenga un método set._ _iter_ _():

image

      A continuación, debemos comprobar que este método devuelva un iterador. Si así fuera, el conjunto sería un objeto iterable. Vamos allá:

image

      Ahora falta una condición para poder afirmar que obj es un interador. Su método obj._ _next_ _() debe devolver a cada llamada el elemento siguiente del contenedor y generar una excepción del tipo StopIteration cuando los elementos han terminado:

image

      En definitiva, las instancias del tipo set son objetos iterables porque tienen un método set._ _iter_ _() que devuelve un iterador, pero no son iteradores porque no tienen el método set._ _next_ _().

      Las funciones integradas iter() y next() también permiten iterar manualmente sobre un objeto iterable:

image

      Una carácterística importante de los iteradores es que quedan vinculados al objeto iterable:

image

      Profundizaremos en este argumento en el Capítulo 6.

      Las clases integradas range y enumerate

      En el Capítulo 2 trataremos las funciones integradas vinculadas a los objetos iterables; de momento

Скачать книгу