GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing docs.python.org — 8. Errores y excepciones 8. Errores y excepciones¶Hasta ahora los mensajes de error apenas habían sido mencionados, pero si has probado los ejemplos anteriores probablemente hayas visto algunos. Hay (al menos) dos tipos diferentes de errores: errores de sintaxis y excepciones. 8.1. Errores de sintaxis¶Los errores de sintaxis, también conocidos como errores de interpretación, son quizás el tipo de queja más común que tenés cuando todavía estás aprendiendo Python: >>> while True print('Hello world') File "<stdin>", line 1 while True print('Hello world') ^^^^^ SyntaxError: invalid syntax The parser repeats the offending line and displays little arrows pointing
at the place where the error was detected. Note that this is not always the
place that needs to be fixed. In the example, the error is detected at the
function The file name ( 8.2. Excepciones¶Incluso si una declaración o expresión es sintácticamente correcta, puede generar un error cuando se intenta ejecutar. Los errores detectados durante la ejecución se llaman excepciones, y no son incondicionalmente fatales: pronto aprenderás a gestionarlos en programas Python. Sin embargo, la mayoría de las excepciones no son gestionadas por el código, y resultan en mensajes de error como los mostrados aquí: >>> 10 * (1/0) Traceback (most recent call last): File "<stdin>", line 1, in <module> 10 * (1/0) ~^~ ZeroDivisionError: division by zero >>> 4 + spam*3 Traceback (most recent call last): File "<stdin>", line 1, in <module> 4 + spam*3 ^^^^ NameError: name 'spam' is not defined >>> '2' + 2 Traceback (most recent call last): File "<stdin>", line 1, in <module> '2' + 2 ~~~~^~~ TypeError: can only concatenate str (not "int") to str La última línea de los mensajes de error indica qué ha sucedido. Hay excepciones de diferentes tipos, y el tipo se imprime como parte del mensaje: los tipos en el ejemplo son: El resto de la línea provee información basado en el tipo de la excepción y qué la causó. La parte anterior del mensaje de error muestra el contexto donde ocurrió la excepción, en forma de seguimiento de pila. En general, contiene un seguimiento de pila que enumera las líneas de origen; sin embargo, no mostrará las líneas leídas desde la entrada estándar. Built-in Exceptions lista las excepciones predefinidas y sus significados. 8.3. Gestionando excepciones¶Es posible escribir programas que gestionen determinadas excepciones. Véase el siguiente ejemplo, que le pide al usuario una entrada hasta que ingrese un entero válido, pero permite al usuario interrumpir el programa (usando Control-C o lo que soporte el sistema operativo); nótese que una interrupción generada por el usuario es señalizada generando la excepción >>> while True: ... try: ... x = int(input("Please enter a number: ")) ... break ... except ValueError: ... print("Oops! That was no valid number. Try again...") ... La sentencia
A ... except RuntimeError, TypeError, NameError: ... pass A class in an class B(Exception): pass class C(B): pass class D(C): pass for cls in [B, C, D]: try: raise cls() except D: print("D") except C: print("C") except B: print("B") Nótese que si las cláusulas except estuvieran invertidas (con Cuando ocurre una excepción, puede tener un valor asociado, también conocido como el argumento de la excepción. La presencia y el tipo de argumento depende del tipo de excepción. La cláusula except puede especificar una variable después del nombre de la excepción. La variable está ligada a la instancia de la excepción, que normalmente tiene un atributo >>> try: ... raise Exception('spam', 'eggs') ... except Exception as inst: ... print(type(inst)) # the exception type ... print(inst.args) # arguments stored in .args ... print(inst) # __str__ allows args to be printed directly, ... # but may be overridden in exception subclasses ... x, y = inst.args # unpack args ... print('x =', x) ... print('y =', y) ... <class 'Exception'> ('spam', 'eggs') ('spam', 'eggs') x = spam y = eggs La salida
El patrón más común para gestionar import sys try: f = open('myfile.txt') s = f.readline() i = int(s.strip()) except OSError as err: print("OS error:", err) except ValueError: print("Could not convert data to an integer.") except Exception as err: print(f"Unexpected {err=}, {type(err)=}") raise La declaración for arg in sys.argv[1:]: try: f = open(arg, 'r') except OSError: print('cannot open', arg) else: print(arg, 'has', len(f.readlines()), 'lines') f.close() El uso de la cláusula Los gestores de excepciones no sólo gestionan excepciones que ocurren inmediatamente en la cláusula try, sino también aquellas que ocurren dentro de funciones que son llamadas (incluso indirectamente) en la cláusula try. Por ejemplo: >>> def this_fails(): ... x = 1/0 ... >>> try: ... this_fails() ... except ZeroDivisionError as err: ... print('Handling run-time error:', err) ... Handling run-time error: division by zero 8.4. Lanzando excepciones¶La declaración >>> raise NameError('HiThere') Traceback (most recent call last): File "<stdin>", line 1, in <module> raise NameError('HiThere') NameError: HiThere El único argumento de raise ValueError # shorthand for 'raise ValueError()' Si es necesario determinar si una excepción fue lanzada pero sin intención de gestionarla, una versión simplificada de la instrucción >>> try: ... raise NameError('HiThere') ... except NameError: ... print('An exception flew by!') ... raise ... An exception flew by! Traceback (most recent call last): File "<stdin>", line 2, in <module> raise NameError('HiThere') NameError: HiThere 8.5. Encadenamiento de excepciones¶Si se produce una excepción no gestionada dentro de una sección >>> try: ... open("database.sqlite") ... except OSError: ... raise RuntimeError("unable to handle error") ... Traceback (most recent call last): File "<stdin>", line 2, in <module> open("database.sqlite") ~~~~^^^^^^^^^^^^^^^^^^^ FileNotFoundError: [Errno 2] No such file or directory: 'database.sqlite' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "<stdin>", line 4, in <module> raise RuntimeError("unable to handle error") RuntimeError: unable to handle error Para indicar que una excepción es consecuencia directa de otra, la sentencia # exc must be exception instance or None. raise RuntimeError from exc Esto puede resultar útil cuando está transformando excepciones. Por ejemplo: >>> def func(): ... raise ConnectionError ... >>> try: ... func() ... except ConnectionError as exc: ... raise RuntimeError('Failed to open database') from exc ... Traceback (most recent call last): File "<stdin>", line 2, in <module> func() ~~~~^^ File "<stdin>", line 2, in func ConnectionError The above exception was the direct cause of the following exception: Traceback (most recent call last): File "<stdin>", line 4, in <module> raise RuntimeError('Failed to open database') from exc RuntimeError: Failed to open database También permite deshabilitar el encadenamiento automático de excepciones utilizando el modismo >>> try: ... open('database.sqlite') ... except OSError: ... raise RuntimeError from None ... Traceback (most recent call last): File "<stdin>", line 4, in <module> raise RuntimeError from None RuntimeError Para obtener más información sobre la mecánica del encadenamiento, consulte Built-in Exceptions. 8.6. Excepciones definidas por el usuario¶Los programas pueden nombrar sus propias excepciones creando una nueva clase excepción (mirá Clases para más información sobre las clases de Python). Las excepciones, típicamente, deberán derivar de la clase Las clases de Excepción pueden ser definidas de la misma forma que cualquier otra clase, pero es habitual mantenerlas lo más simples posible, a menudo ofreciendo solo un número de atributos con información sobre el error que leerán los gestores de la excepción. La mayoría de las excepciones se definen con nombres acabados en «Error», de manera similar a la nomenclatura de las excepciones estándar. Muchos módulos estándar definen sus propias excepciones para reportar errores que pueden ocurrir en funciones propias. 8.7. Definiendo acciones de limpieza¶La declaración >>> try: ... raise KeyboardInterrupt ... finally: ... print('Goodbye, world!') ... Goodbye, world! Traceback (most recent call last): File "<stdin>", line 2, in <module> raise KeyboardInterrupt KeyboardInterrupt Si una cláusula
Por ejemplo: >>> def bool_return(): ... try: ... return True ... finally: ... return False ... >>> bool_return() False Un ejemplo más complicado: >>> def divide(x, y): ... try: ... result = x / y ... except ZeroDivisionError: ... print("division by zero!") ... else: ... print("result is", result) ... finally: ... print("executing finally clause") ... >>> divide(2, 1) result is 2.0 executing finally clause >>> divide(2, 0) division by zero! executing finally clause >>> divide("2", "1") executing finally clause Traceback (most recent call last): File "<stdin>", line 1, in <module> divide("2", "1") ~~~~~~^^^^^^^^^^ File "<stdin>", line 3, in divide result = x / y ~~^~~ TypeError: unsupported operand type(s) for /: 'str' and 'str' Como se puede ver, la cláusula En aplicaciones reales, la cláusula 8.8. Acciones predefinidas de limpieza¶Algunos objetos definen acciones de limpieza estándar para llevar a cabo cuando el objeto ya no necesario, independientemente de que las operaciones sobre el objeto hayan sido exitosas o no. Véase el siguiente ejemplo, que intenta abrir un archivo e imprimir su contenido en la pantalla. for line in open("myfile.txt"): print(line, end="") El problema con este código es que deja el archivo abierto por un periodo de tiempo indeterminado luego de que esta parte termine de ejecutarse. Esto no es un problema en scripts simples, pero puede ser un problema en aplicaciones más grandes. La declaración with open("myfile.txt") as f: for line in f: print(line, end="") Una vez que la declaración se ejecuta, el fichero f siempre se cierra, incluso si aparece algún error durante el procesado de las líneas. Los objetos que, como los ficheros, posean acciones predefinidas de limpieza lo indicarán en su documentación. 8.9. Lanzando y gestionando múltiples excepciones no relacionadas¶Hay situaciones en las que es necesario informar de varias excepciones que se han producido. Este es a menudo el caso en los marcos de concurrencia, cuando varias tareas pueden haber fallado en paralelo, pero también hay otros casos de uso en los que es deseable continuar la ejecución y recoger múltiples errores en lugar de lanzar la primera excepción. El incorporado >>> def f(): ... excs = [OSError('error 1'), SystemError('error 2')] ... raise ExceptionGroup('there were problems', excs) ... >>> f() + Exception Group Traceback (most recent call last): | File "<stdin>", line 1, in <module> | f() | ~^^ | File "<stdin>", line 3, in f | raise ExceptionGroup('there were problems', excs) | ExceptionGroup: there were problems (2 sub-exceptions) +-+---------------- 1 ---------------- | OSError: error 1 +---------------- 2 ---------------- | SystemError: error 2 +------------------------------------ >>> try: ... f() ... except Exception as e: ... print(f'caught {type(e)}: {e}') ... caught <class 'ExceptionGroup'>: there were problems (2 sub-exceptions) >>> Utilizando >>> def f(): ... raise ExceptionGroup( ... "group1", ... [ ... OSError(1), ... SystemError(2), ... ExceptionGroup( ... "group2", ... [ ... OSError(3), ... RecursionError(4) ... ] ... ) ... ] ... ) ... >>> try: ... f() ... except* OSError as e: ... print("There were OSErrors") ... except* SystemError as e: ... print("There were SystemErrors") ... There were OSErrors There were SystemErrors + Exception Group Traceback (most recent call last): | File "<stdin>", line 2, in <module> | f() | ~^^ | File "<stdin>", line 2, in f | raise ExceptionGroup( | ...<12 lines>... | ) | ExceptionGroup: group1 (1 sub-exception) +-+---------------- 1 ---------------- | ExceptionGroup: group2 (1 sub-exception) +-+---------------- 1 ---------------- | RecursionError: 4 +------------------------------------ >>> Tenga en cuenta que las excepciones anidadas en un grupo de excepciones deben ser instancias, no tipos. Esto se debe a que en la práctica las excepciones serían típicamente las que ya han sido planteadas y capturadas por el programa, siguiendo el siguiente patrón: >>> excs = [] >>> for test in tests: ... try: ... test.run() ... except Exception as e: ... excs.append(e) ... >>> if excs: ... raise ExceptionGroup("Test Failures", excs) ... 8.10. Enriqueciendo excepciones con notas¶Cuando se crea una excepción para ser lanzada, normalmente se inicializa con información que describe el error que se ha producido. Hay casos en los que es útil añadir información después de que la excepción haya sido capturada. Para este propósito, las excepciones tienen un método >>> try: ... raise TypeError('bad type') ... except Exception as e: ... e.add_note('Add some information') ... e.add_note('Add some more information') ... raise ... Traceback (most recent call last): File "<stdin>", line 2, in <module> raise TypeError('bad type') TypeError: bad type Add some information Add some more information >>> Por ejemplo, al recopilar excepciones en un grupo de excepciones, es posible que queramos añadir información de contexto para los errores individuales. A continuación, cada excepción del grupo tiene una nota que indica cuándo se ha producido ese error. >>> def f(): ... raise OSError('operation failed') ... >>> excs = [] >>> for i in range(3): ... try: ... f() ... except Exception as e: ... e.add_note(f'Happened in Iteration {i+1}') ... excs.append(e) ... >>> raise ExceptionGroup('We have some problems', excs) + Exception Group Traceback (most recent call last): | File "<stdin>", line 1, in <module> | raise ExceptionGroup('We have some problems', excs) | ExceptionGroup: We have some problems (3 sub-exceptions) +-+---------------- 1 ---------------- | Traceback (most recent call last): | File "<stdin>", line 3, in <module> | f() | ~^^ | File "<stdin>", line 2, in f | raise OSError('operation failed') | OSError: operation failed | Happened in Iteration 1 +---------------- 2 ---------------- | Traceback (most recent call last): | File "<stdin>", line 3, in <module> | f() | ~^^ | File "<stdin>", line 2, in f | raise OSError('operation failed') | OSError: operation failed | Happened in Iteration 2 +---------------- 3 ---------------- | Traceback (most recent call last): | File "<stdin>", line 3, in <module> | f() | ~^^ | File "<stdin>", line 2, in f | raise OSError('operation failed') | OSError: operation failed | Happened in Iteration 3 +------------------------------------ >>>
© Derechos de autor 2001 Python Software Foundation.
Ésta página tiene la licencia Python Software Foundation Versión 2. Ejemplos, guías, y otro código en la documentación están bajo la licencia adicional Zero Clause BSD. Ver Historia y Licencia para más información. La Python Software Foundation es una corporación sin fines de lucro. Por favor dona. Última actualización en nov 12, 2026 (07:48 UTC). Encontraste un bug? Creado usando Sphinx9.1.1. |
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |