Tu país

Las herramientas que lo admiten usan tu país para la moneda local, el formato de los números, las unidades y el tamaño del papel. Tu elección se guarda solo en este navegador.

Escribe un nombre o un código de dos letras. Usa las flechas arriba y abajo para recorrer los países, Intro para elegir uno y Escape para cerrar.

Python  Módulo 1 – Primeros pasos: instalar, ejecutar y leer Python

Leer mensajes de error y tracebacks con calma

Lee un traceback de Python de abajo arriba, reconoce los errores más comunes al empezar y usa los mensajes más claros de Python 3.14 para arreglar la línea que falla.

Lección gratis, respuestas Pro: 25 minutos
Gratis: la lección completa. Con un pase: las respuestas modelo de sus 2 preguntas de entrevista.

Qué vas a aprender

  • Leer un traceback de abajo arriba para encontrar la línea que falla
  • Predecir si un archivo llega a ejecutarse cuando tiene un error de sintaxis
  • Reconocer las excepciones más comunes al empezar y sus causas habituales
  • Usar help(), la documentación y ejemplos mínimos para desatascarte

Antes de empezar

Qué vas a aprender · Antes de empezar

Qué vas a aprender

  • Leer un traceback de abajo arriba para encontrar la línea que falla
  • Predecir si un archivo llega a ejecutarse cuando tiene un error de sintaxis
  • Reconocer las excepciones más comunes al empezar y sus causas habituales
  • Usar help(), la documentación y ejemplos mínimos para desatascarte

Antes de empezar

En esta página

Un solo artículo mal escrito, cofee, detiene el programa de facturación de esta lección con un informe de once líneas, y la errata se encuentra en segundos en cuanto sabes qué línea del informe leer primero.

Cuando un programa falla, Python se detiene e imprime un traceback: El informe que imprime Python cuando una excepción termina un programa: las llamadas que llevaron a la línea que falla, la más antigua primero, y en la última línea el tipo y el mensaje de la excepción. Más en “Manejar excepciones con try y except” (en inglés). Los primeros asustan, pero un traceback es un informe preciso con tres partes: qué salió mal, la línea donde ocurrió y la cadena de llamadas que llevó hasta allí. Leerlo en ese orden, de abajo arriba, es la forma más rápida de encontrar la mayoría de los errores.

Léelo de abajo arriba

Este programa suma dos cuentas. La primera funciona; la segunda tiene una errata en su pedido:

Un traceback a través de tres funciones Python · bill.py
prices = {"tea": 30, "toast": 45, "coffee": 60}


def line_total(item, quantity):
    return prices[item] * quantity


def bill(order):
    total = 0
    for item, quantity in order:
        total += line_total(item, quantity)
    return total


print("First bill:", bill([("tea", 2), ("toast", 1)]))
print("Second bill:", bill([("tea", 1), ("cofee", 2)]))

Salida (código de salida 1)

First bill: 105

Impreso como error (salida de errores estándar)

Traceback (most recent call last):
  File "bill.py", line 16, in <module>
    print("Second bill:", bill([("tea", 1), ("cofee", 2)]))
                          ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "bill.py", line 11, in bill
    total += line_total(item, quantity)
             ~~~~~~~~~~^^^^^^^^^^^^^^^^
  File "bill.py", line 5, in line_total
    return prices[item] * quantity
           ~~~~~~^^^^^^
KeyError: 'cofee'

Salida registrada con Python 3.14.8 en macOS 26 arm64. Para ejecutarlo tú: mise exec python@3.14.8 -- python3 bill.py

Empieza por la última línea y sube:

  1. La última línea nombra la excepción y da su mensaje. KeyError: 'cofee' dice que se pidió a un diccionario una clave que no tiene, y el mensaje es esa clave.
  2. El marco justo encima muestra dónde ocurrió: File "bill.py", line 5, in line_total y después la propia línea. Las marcas ~ y ^ debajo señalan la parte de la línea que falló, la consulta prices[item].
  3. Cada marco más arriba es una llamada que llevó hasta allí. bill() llamó a line_total() en la línea 11, y el nivel superior del archivo (<module>) llamó a bill() en la línea 16. “Most recent call last” (la llamada más reciente, la última) significa que los marcos van desde la primera llamada hasta la línea que falló.

Cada bloque de dos o tres líneas del informe es un marco: El registro de una llamada a una función que no ha terminado: sus variables locales y el punto donde continuar cuando vuelva la llamada que espera. Más en “Recursión, la pila de llamadas y sus límites” (en inglés), una llamada que no había terminado cuando ocurrió el error. Recorre las llamadas de la segunda cuenta y el camino del error de vuelta por ellas:

Interactivo · mensaje a mensaje Las llamadas detrás del traceback de bill.py Recorre la segunda cuenta, llamada a llamada, y mira cómo el KeyError sube por las llamadas que llevaron a él.
Las llamadas detrás del traceback de bill.py, paso 8 de 8. Mensajes hasta ahora: de El nivel superior del archivo a bill(): bill(segundo pedido); de bill() a line_total(): line_total('tea', 1); de line_total() a bill(): returns 30; de bill() a line_total(): line_total('cofee', 2); de line_total() a bill(): KeyError: 'cofee'; de bill() a El nivel superior del archivo: KeyError: 'cofee'.El nivel superior del archivo<module>, línea 16bill()line 11line_total()line 5bill(segundo pedido)line_total('tea', 1)returns 30line_total('cofee', 2)KeyError: 'cofee'KeyError: 'cofee'

El dibujo muestra la escena completa; sus 8 pasos aparecen abajo.

Todos los pasos en texto
  1. La línea 16 invoca bill(). La primera cuenta ya imprimió 105. Ahora la línea 16 invoca bill() con el segundo pedido: un tea y dos cofee, escrito con una sola f.
  2. bill() invoca line_total(). Dentro de bill(), la línea 11 invoca line_total() para el primer artículo. tea está en la lista de precios, así que la consulta de la línea 5 funciona.
  3. Vuelve 30. line_total() devuelve 30, un tea a 30, y bill() lo suma al total.
  4. El segundo artículo. La línea 11 se ejecuta otra vez, ahora para el segundo artículo del pedido.
  5. La consulta falla. La línea 5 consulta prices['cofee']. No existe esa clave, así que Python lanza KeyError con la clave como mensaje, y line_total() se detiene en el acto.
  6. El error sale de line_total(). Nada en line_total() maneja el error, así que sale de la función y llega a bill(), a la línea 11, donde se hizo la llamada. bill() también se detiene.
  7. Hasta el nivel superior. bill() tampoco lo maneja, así que el error llega al nivel superior del archivo en la línea 16. Ya no queda nada que lo maneje, y el programa termina.
  8. El traceback enumera el camino de bajada. Python imprime las llamadas en el orden en que se hicieron, la línea 16, después la 11 y después la 5, con la excepción al final. Léelo desde abajo: el error, la línea que falló y después cada llamada que llevó hasta allí.

La línea que falló no siempre es la que hay que arreglar. A line_total() no le pasa nada: recibió un valor incorrecto. Sigue leyendo hacia arriba hasta llegar a la línea de donde vino el valor incorrecto, aquí el pedido de la línea 16. Fíjate también en que la primera cuenta se imprimió: todo lo anterior a la línea que falla se ejecutó con normalidad. Pulsa Editar, corrige cofee en la línea 16 y ejecútalo: se imprimen las dos cuentas, y la segunda es 150.

Idea clave

Lee un traceback desde abajo: la última línea dice qué salió mal, el marco de encima dice dónde, y los marcos más arriba dicen cómo llegó el programa hasta allí. La línea que hay que arreglar es la de donde vino el valor incorrecto.

Cuando los marcos que fallan no son tu código

Si pasas algo incorrecto a una función de la biblioteca estándar o de un paquete, los últimos marcos están dentro de los propios archivos de esa función:

Un traceback que termina en la biblioteca estándar Python · bad_json.py
import json

settings_text = "{'theme': 'dark'}"
settings = json.loads(settings_text)
print("Theme:", settings["theme"])

Salida (código de salida 1)

Impreso como error (salida de errores estándar)

Traceback (most recent call last):
  File "bad_json.py", line 4, in <module>
    settings = json.loads(settings_text)
  File "…/lib/python3.14/json/__init__.py", line 352, in loads
    return _default_decoder.decode(s)
           ~~~~~~~~~~~~~~~~~~~~~~~^^^
  File "…/lib/python3.14/json/decoder.py", line 345, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
               ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
  File "…/lib/python3.14/json/decoder.py", line 361, in raw_decode
    obj, end = self.scan_once(s, idx)
               ~~~~~~~~~~~~~~^^^^^^^^
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

Salida registrada con Python 3.14.8 en macOS 26 arm64. Para ejecutarlo tú: mise exec python@3.14.8 -- python3 bad_json.py

Los marcos bajo …/lib/python3.14/json/ pertenecen al módulo json de Python (… representa la carpeta en la que está instalado Python, que cambia de una computadora a otra). No busques un error ahí. Busca el último marco que está en tu propio archivo, la línea 4, donde se llamó a json.loads(), y comprueba qué le diste. El mensaje dice el resto: JSON necesita comillas dobles alrededor de los nombres, así que el texto debería haber sido '{"theme": "dark"}'.

Validador de JSON (en inglés) Pega un texto JSON para ver la línea y la columna exactas en las que deja de ser JSON válido.

Punto de control

Comprueba: leer un traceback de abajo arriba

  1. Pregunta 1 de 2 ¿Por dónde empiezas a leer un traceback?

    Elige una respuesta.

    Ver la respuesta: pregunta 1 de 2

    Respuesta: Por la última línea, que nombra la excepción y su mensaje

    Un traceback se lee mejor de abajo arriba: la excepción y su mensaje, después el marco de la línea que falló y después las llamadas de encima que llevaron hasta allí.

  2. Pregunta 2 de 2 bill.py se detiene con KeyError: 'cofee', lanzado en la línea 5 dentro de line_total(). ¿Qué línea cambias para arreglar la segunda cuenta?

    Elige una respuesta.

    Una pista

    ¿Le pasa algo a la propia consulta?

    Ver la respuesta: pregunta 2 de 2

    Respuesta: La línea 16, donde el pedido escribe mal coffee

    La línea que falló no siempre es la que hay que arreglar. La línea 5 hizo su trabajo; el valor que recibió venía del pedido de la línea 16, que es donde está la errata.

Un SyntaxError significa que no se ejecutó nada

Python lee un archivo entero antes de ejecutar nada de él. Cuando la gramática está mal, informa de un SyntaxError y no ejecuta nada en absoluto, ni siquiera las líneas de encima del error:

Una palabra clave mal escrita Python · typo_keyword.py
print("This line never runs")


def greeting(name):
    retrun "Hello, " + name


print(greeting("Asha"))

Salida (código de salida 1)

Impreso como error (salida de errores estándar)

  File "typo_keyword.py", line 5
    retrun "Hello, " + name
    ^^^^^^
SyntaxError: invalid syntax. Did you mean 'return'?

Salida registrada con Python 3.14.8 en macOS 26 arm64. Para ejecutarlo tú: mise exec python@3.14.8 -- python3 typo_keyword.py

Esta vez no hay línea “Traceback (most recent call last)”, porque no hubo ninguna llamada: el archivo nunca empezó. La primera línea, un print(), no imprimió nada por la misma razón. Pulsa Editar, corrige retrun por return y ejecútalo: ahora se ejecutan las dos llamadas a print(), incluida la primera.

Nota de versión

Novedad de Python 3.14: cuando una palabra parece una palabra clave mal escrita, el mensaje sugiere la palabra clave, como en el Did you mean 'return'? de arriba. Python 3.13 y anteriores solo dicen invalid syntax.

A veces la línea que muestra Python parece perfectamente correcta. Entonces la causa suele estar antes, a menudo un corchete o unas comillas que se abrieron y nunca se cerraron. Python señala dónde se abrieron:

Un corchete que nunca se cerró Python · unclosed.py
marks = [72, 88, 95
print(sum(marks) / len(marks))

Salida (código de salida 1)

Impreso como error (salida de errores estándar)

  File "unclosed.py", line 1
    marks = [72, 88, 95
            ^
SyntaxError: '[' was never closed

Salida registrada con Python 3.14.8 en macOS 26 arm64. Para ejecutarlo tú: mise exec python@3.14.8 -- python3 unclosed.py

La lista de la línea 1 nunca recibe su ]. Dentro de unos corchetes Python sigue leyendo las líneas siguientes, así que llega al final del archivo todavía dentro de la lista, e informa de la línea en la que empezó la lista. IndentationError, para líneas con una sangría que no encaja con los bloques de alrededor, también es un tipo de SyntaxError y se informa igual, antes de que se ejecute nada.

Punto de control

Comprueba: un SyntaxError significa que no se ejecutó nada

  1. Pregunta 1 de 2 typo_keyword.py tiene print("This line never runs") en la línea 1 y retrun en la línea 5. ¿Qué imprime antes del informe de error?

    Elige una respuesta.

    Ver la respuesta: pregunta 1 de 2

    Respuesta: Nada, porque el SyntaxError detiene el archivo antes de que se ejecute ninguna línea

    Un SyntaxError se detecta mientras Python compila el archivo entero, antes de que se ejecute nada, así que ni siquiera el print() de la línea 1 imprime. El informe muestra el archivo y la línea, sin la línea Traceback.

  2. Pregunta 2 de 2 Python informa de un SyntaxError en la línea 12, y la línea 12 parece perfectamente correcta. ¿Dónde miras a continuación?

    Elige una respuesta.

    Ver la respuesta: pregunta 2 de 2

    Respuesta: Encima de ella, en busca de un corchete o unas comillas que se abrieron y nunca se cerraron

    Cuando la línea que se muestra parece correcta, la causa suele estar antes: un corchete o unas comillas abiertos y nunca cerrados. Desde Python 3.10, un corchete sin cerrar se informa en la línea donde se abrió.

Cada excepción común señala un tipo de error

Cada una de estas ocho líneas comete un error distinto. El programa las ejecuta una a una e imprime la última línea de cada traceback, así que ves los mensajes exactos de esta versión de Python:

Ocho errores comunes y sus mensajes Python · error_gallery.py
import traceback

# Eight one-line mistakes. exec() runs each line as a tiny program and the error is caught,
# so you see the last line of every traceback, exactly as Python prints it.
mistakes = [
    "print(scroe)",
    '"3" + 4',
    'int("three")',
    "[10, 20, 30][3]",
    '{"tea": 30}["coffee"]',
    '"text".uper()',
    "1 / 0",
    "import numpyy",
]
for code in mistakes:
    try:
        exec(code)
    except Exception as error:
        last_line = traceback.format_exception_only(error)[-1].strip()
        print(f"{code:<24}{last_line}")

Salida

print(scroe)            NameError: name 'scroe' is not defined
"3" + 4                 TypeError: can only concatenate str (not "int") to str
int("three")            ValueError: invalid literal for int() with base 10: 'three'
[10, 20, 30][3]         IndexError: list index out of range
{"tea": 30}["coffee"]   KeyError: 'coffee'
"text".uper()           AttributeError: 'str' object has no attribute 'uper'. Did you mean: 'upper'?
1 / 0                   ZeroDivisionError: division by zero
import numpyy           ModuleNotFoundError: No module named 'numpyy'

Salida registrada con Python 3.14.8 en macOS 26 arm64. Para ejecutarlo tú: mise exec python@3.14.8 -- python3 error_gallery.py

Cuando un nombre o un atributo está mal escrito y existe algo parecido, Python añade Did you mean …?, como para uper arriba. Pulsa Editar, añade a la lista un error tuyo, como '"5" * "2"', y ejecútalo para ver su mensaje. Lo que suele significar cada error, y dónde mirar primero:

Error Suele significar Mira primero
NameError Se usa un nombre que nunca se asignó, o que está mal escrito La ortografía, y si la línea que lo asigna se ejecutó antes
TypeError Un valor del tipo equivocado para la operación, como texto más un número Los tipos implicados: convierte con int(), float() o str()
ValueError El tipo correcto con un valor que no encaja, como int("three") Los datos, a menudo lo que escribió el usuario o lo que contenía un archivo
IndexError Una posición más allá del final de una lista: la última es len(items) - 1 Un bucle o un cálculo que llega un paso demasiado lejos
KeyError Un diccionario no tiene esa clave; el mensaje es la clave La ortografía de la clave, o usa .get() cuando pueda faltar
AttributeError El objeto no tiene ningún método ni atributo con ese nombre La ortografía y el tipo del objeto: print(type(value))
ZeroDivisionError División entre cero Cuentas y longitudes que pueden ser 0, como una lista vacía
ModuleNotFoundError No hay ningún módulo con ese nombre para este Python La ortografía, y si el paquete está instalado en el entorno que ejecutas
IndentationError Una sangría que no encaja con los bloques Falta una línea con sangría después de dos puntos, o se mezclan tabuladores con espacios
RecursionError Una función que se llamó a sí misma sin parar, por defecto hasta unos 1000 niveles El caso que debería detener la recursión

Un error común: un archivo con el nombre de un módulo

Ponle a tu archivo el nombre de un módulo que importas, como random.py, y Python importa tu archivo en lugar del módulo. Python 3.13 y posteriores lo notan y lo dicen:

Un archivo llamado random.py Python · shadow/random.py
import random

print("Your dice roll:", random.randint(1, 6))

Salida (código de salida 1)

Impreso como error (salida de errores estándar)

Traceback (most recent call last):
  File "random.py", line 1, in <module>
    import random
  File "random.py", line 3, in <module>
    print("Your dice roll:", random.randint(1, 6))
                             ^^^^^^^^^^^^^^
AttributeError: module 'random' has no attribute 'randint' (consider renaming 'random.py' since it has the same name as the standard library module named 'random' and prevents importing that standard library module)

Salida registrada con Python 3.14.8 en macOS 26 arm64. Para ejecutarlo tú: mise exec python@3.14.8 -- python3 random.py

El script se importa a sí mismo como random, así que random.randint no existe. El mensaje incluso nombra el archivo que hay que renombrar: llámalo dice.py y import random vuelve a encontrar el módulo de la biblioteca estándar. Python 3.12 y anteriores informan del mismo error solo como un “partially initialized module” (módulo inicializado a medias) y una posible importación circular.

Punto de control

Comprueba: lo que señalan las excepciones comunes

  1. Pregunta 1 de 2 ¿Qué excepción lanza int("three")?

    Elige una respuesta.

    Ver la respuesta: pregunta 1 de 2

    Respuesta: ValueError

    int("three") recibe un argumento del tipo correcto con un valor que no encaja, que es lo que significa ValueError. El mensaje nombra el texto: invalid literal for int() with base 10: 'three'.

  2. Pregunta 2 de 2 marks = [72, 88, 95]. ¿Qué excepción lanza marks[3], y por qué?

    Elige una respuesta.

    Ver la respuesta: pregunta 2 de 2

    Respuesta: IndexError, porque las posiciones de una lista de 3 elementos son 0, 1 y 2

    Una lista de 3 elementos tiene las posiciones 0 a 2, así que marks[3] lanza IndexError: list index out of range. Busca un bucle o un cálculo que llega un paso demasiado lejos.

Los mensajes de Python se hicieron más claros, versión a versión

Python 3.14 también mejoró otros mensajes. Usar una lista como clave de un diccionario falla, como antes, porque las claves deben ser hashable: Un valor que puede ser una clave de un dict o un elemento de un set, porque su hash nunca cambia mientras existe: los números, las cadenas y las tuplas de valores hashables son hashables; las listas, los dicts y los sets no. Más en “functools: cache, partial, reduce y más” (en inglés), y una lista, que puede cambiar, no lo es; pero ahora el mensaje dice lo que intentabas hacer:

Una lista como clave de un diccionario Python · unhashable.py
stock = {}
stock[["tea", "toast"]] = 2

Salida (código de salida 1)

Impreso como error (salida de errores estándar)

Traceback (most recent call last):
  File "unhashable.py", line 2, in <module>
    stock[["tea", "toast"]] = 2
    ~~~~~^^^^^^^^^^^^^^^^^^
TypeError: cannot use 'list' as a dict key (unhashable type: 'list')

Salida registrada con Python 3.14.8 en macOS 26 arm64. Para ejecutarlo tú: mise exec python@3.14.8 -- python3 unhashable.py

Nota de versión

Python 3.13 y anteriores se quedan en TypeError: unhashable type: 'list'. Dos mejoras más antiguas se ven en todos los tracebacks de esta lección: desde Python 3.11, las marcas ~ y ^ señalan la parte exacta de una línea que falló (PEP 657), y desde Python 3.13 los tracebacks en un terminal salen en color, que las variables de entorno PYTHON_COLORS=0 y NO_COLOR=1 desactivan. Las páginas de novedades (What’s New) enumeran todas las mejoras, versión a versión.

Cada versión con novedades desde la 3.10 ha añadido mensajes como estos, así que el mismo error se lee de otra forma en un Python más antiguo. Recorre lo que cambió cada versión:

Cronología · 5 momentos en orden Cómo se hicieron más claros los mensajes de error de Python, versión a versión Recorre las versiones en orden. Cada una cambió lo que te dice un traceback o un SyntaxError.
  1. 3.10

    Corchetes sin cerrar y dos puntos que se esperaban SyntaxError

    Un corchete que nunca se cierra se informa donde se abre, como '[' was never closed, en lugar de al final del archivo, y unos dos puntos que faltan dan expected ':'. NameError y AttributeError añaden Did you mean …? cuando existe un nombre parecido.

  2. 3.11

    Marcas bajo la parte que falló tracebacks

    Los tracebacks ponen ~ y ^ bajo la parte exacta de una línea que falló, como prices[item] dentro de una expresión más larga (PEP 657).

  3. 3.12

    Sugerencias de importaciones que faltan

    Un NameError por un módulo estándar que olvidaste importar dice Did you forget to import 'sys'?, y una importación from fallida sugiere el nombre que querías decir.

  4. 3.13

    Color, y archivos con nombre de módulo

    Los tracebacks en un terminal salen en color. A un script con el nombre de un módulo estándar, como random.py, se le sugiere que considere renombrarlo, y un argumento con nombre mal escrito recibe Did you mean …?

  5. 3.14

    Palabras clave mal escritas y claves no hashables este curso

    Una palabra clave mal escrita como retrun recibe Did you mean 'return'?, y una lista usada como clave de un dict recibe cannot use 'list' as a dict key. Estos son los mensajes que imprimen los ejemplos de esta lección.

La cronología tiene 5 momentos, de 3.10 a 3.14.

En el Python que ejecutas, los mensajes más nuevos son la ayuda que recibes. En uno más antiguo, como el Python de un servidor, espera solo la redacción antigua, y lee tú mismo la parte marcada de la línea.

Punto de control

Comprueba: mensajes de error según la versión de Python

  1. Una pregunta En Python 3.13, la línea retrun "Hello, " + name está en una función. ¿Qué dice el SyntaxError?

    Elige una respuesta.

    Ver la respuesta: una pregunta

    Respuesta: invalid syntax, sin ninguna sugerencia

    Python 3.14 añadió Did you mean 'return'? a este SyntaxError. En la 3.13 y anteriores el mismo archivo se detiene solo con SyntaxError: invalid syntax, así que en un Python más antiguo busca tú mismo las erratas en la palabra marcada.

  1. Lee la última línea despacio y busca la excepción en la página Built-in Exceptions (excepciones integradas) de la documentación de Python. En el intérprete, help() muestra la documentación de una función, un tipo o un módulo, y issubclass() te dice a qué tipo de error más amplio pertenece una excepción:

    Preguntar al propio Python Consola de Python · help_session.pycon
    >>> help(len)
    Help on built-in function len in module builtins:
    
    len(obj, /)
        Return the number of items in a container.
    
    >>> issubclass(KeyError, LookupError)
    True
    >>> issubclass(ModuleNotFoundError, ImportError)
    True

    Esta sesión se reprodujo con Python 3.14.8 en macOS 26 arm64 e imprimió exactamente lo que se muestra.

  2. Imprime lo que tienes. Justo encima de la línea que falla, añade print(repr(value), type(value)) para los valores que usa. La mayoría de las sorpresas son un valor de otro tipo, o un texto con un espacio que no se ve.

  3. Haz un ejemplo mínimo. Copia el programa y borra todo lo que no hace falta para que ocurra el error, hasta que queden unas pocas líneas. A menudo encuentras el error por el camino; si no, esas pocas líneas son lo que enseñas cuando pides ayuda.

  4. Busca la última línea, sin los nombres y los valores propios de tu programa.

Recorre los cuatro pasos sobre el KeyError de bill.py:

Interactivo · etapa por etapa Cuatro pasos para desatascarte Recorre los pasos sobre el KeyError de bill.py. Cada paso encuentra el error o te deja un problema más pequeño.
Cuatro pasos para desatascarte, paso 5 de 5. Se ve: Lee la última línea, Imprime los valores que usa, Haz un ejemplo mínimo, Busca la última línea. Resaltado: Lee la última línea.¿un error nuevo? vuelve a empezarLee la última líneaKeyError: 'cofee'Imprime los valores que usarepr(value), type(value)Haz un ejemplo mínimounas pocas líneas que siguen fallandoBusca la última líneasin tus propios nombressiguiente traceback

El dibujo muestra la escena completa; sus 5 pasos aparecen abajo.

Todos los pasos en texto
  1. Lee la última línea. KeyError: 'cofee' dice qué salió mal: un diccionario no tiene la clave 'cofee'. El mensaje es la clave, así que la siguiente pregunta es de dónde vino esa clave.
  2. Imprime lo que tienes. Encima de la línea que falla, print(repr(item), type(item)) muestra el valor exacto. repr() muestra lo que print() oculta, como el espacio al final de 'coffee ' en print_values.py.
  3. Reduce el programa. Borra todo lo que el error no necesita. bill.py se queda en dos líneas, un dict y una consulta, que siguen lanzando el mismo KeyError: eso es minimal.py.
  4. Busca la última línea. Busca KeyError junto con lo que hacía el código, una consulta a un diccionario, y deja fuera tus propios nombres y valores, como cofee y line_total.
  5. Un error nuevo, los mismos pasos. Arreglar un error a menudo deja que el programa siga hasta el siguiente. Vuelve a empezar desde la última línea del nuevo traceback.

Este es el paso 2 con un valor leído de un archivo: print() muestra el artículo como coffee, y solo repr() muestra el espacio de detrás que hace fallar la consulta:

Lo que print() oculta y repr() muestra Python · print_values.py
prices = {"tea": 30, "coffee": 60}
item = "coffee "  # read from a file, with a space at the end
print(item)
print(repr(item), type(item))
print(item in prices)

Salida

coffee 
'coffee ' <class 'str'>
False

Salida registrada con Python 3.14.8 en macOS 26 arm64. Para ejecutarlo tú: mise exec python@3.14.8 -- python3 print_values.py

Y este es el paso 3 con bill.py: las dos líneas que siguen lanzando el mismo error forman un El programa más pequeño que todavía muestra un error, hecho borrando todo lo que el error no necesita. Hacer uno a menudo encuentra el error; si no, es lo que enseñas cuando pides ayuda.:

bill.py reducido a dos líneas Python · minimal.py
prices = {"coffee": 60}
print(prices["cofee"])

Salida (código de salida 1)

Impreso como error (salida de errores estándar)

Traceback (most recent call last):
  File "minimal.py", line 2, in <module>
    print(prices["cofee"])
          ~~~~~~^^^^^^^^^
KeyError: 'cofee'

Salida registrada con Python 3.14.8 en macOS 26 arm64. Para ejecutarlo tú: mise exec python@3.14.8 -- python3 minimal.py

Seguridad

Antes de pegar código o un traceback en un foro o en un asistente de IA, quita las contraseñas, las claves de API, los tokens y los datos personales. Los tracebacks contienen rutas de archivo, que a menudo incluyen tu nombre de usuario, y el código de alrededor de cada línea que falla.

Compilador de Python en línea (en inglés) Ejecuta bill.py en tu navegador, selecciona una línea de su traceback para saltar a esa línea y arregla el pedido.

Punto de control

Comprueba: desatascarte

  1. Una pregunta print(repr(item), type(item)) muestra 'coffee ' <class 'str'>, y prices[item] lanza KeyError aunque prices tiene una clave "coffee". ¿Por qué?

    Elige una respuesta.

    Ver la respuesta: una pregunta

    Respuesta: El valor termina en un espacio, así que es una clave distinta de "coffee"

    repr() muestra un valor tal como lo escribirías en el código, comillas y espacios incluidos, así que 'coffee ' delata el espacio del final. print(item) habría mostrado coffee seguido de un espacio invisible.

Practica: arregla una cuenta leyendo sus tracebacks

bill_total() suma un pedido escrito como líneas de texto, y su código inicial falla con dos tracebacks distintos. Ejecuta las pruebas de ejemplo, lee cada traceback de abajo arriba y arregla cada valor incorrecto donde se origina:

Ejercicio · Fácil · Python

Arregla una cuenta leyendo sus tracebacks

bill_total(lines) suma un pedido dado como líneas de texto, cada una con un artículo y una cantidad separados por una coma, como "tea,2", con los precios en PRICES:

  • bill_total(["tea,2", "toast,1"]) devuelve 105.
  • Se permiten espacios alrededor del artículo o de la cantidad: bill_total([" coffee , 2"]) devuelve 120.
  • Un pedido vacío devuelve 0.

El código inicial está casi bien, y falla. Ejecuta las pruebas de ejemplo y lee cada traceback de abajo arriba: la última línea nombra el error, el marco de encima muestra la línea que falló, y el valor incorrecto vino de algún punto anterior a esa línea. Arregla cada valor donde se origina y vuelve a ejecutar las pruebas.

Código inicial · bill.py

PRICES = {"tea": 30, "toast": 45, "coffee": 60}


def bill_total(lines):
    """Add up an order given as lines of text such as "tea,2"."""
    total = 0
    for line in lines:
        item, quantity = line.split(",")
        total += PRICES[item] * quantity
    return total
Las pruebas de ejemplo · test_bill.py
from bill import bill_total


def test_two_lines():
    """adds up each item's price times its quantity"""
    assert bill_total(["tea,2", "toast,1"]) == 105


def test_spaces():
    """allows spaces around the item and the quantity"""
    assert bill_total([" coffee , 2"]) == 120
    assert bill_total(["tea , 1", " toast,2 "]) == 120


def test_empty_order():
    """an empty order costs nothing"""
    assert bill_total([]) == 0
Una pista

El primer traceback termina con TypeError: unsupported operand type(s) for +=: 'int' and 'str' en la línea con +=. Uno de los dos lados es texto: añade print(repr(quantity)) encima de esa línea y vuelve a ejecutar las pruebas. int() convierte un texto como " 2 " en un número, espacios incluidos. El siguiente traceback nombra una clave con espacios, y .strip() quita los espacios de los dos extremos de una cadena.

Las pruebas de ejemplo se ejecutan en este dispositivo, en tu navegador (Pyodide): no se envía nada a mysmartcopilot.com. La primera ejecución descarga Python (unos 13.5 MB), que se guarda para las siguientes. Una comprobación en tu navegador es una orientación para ti, no la prueba de que el código sea correcto con cualquier entrada.

Después resuelve las preguntas sobre las cinco ideas, de leer marcos a desatascarte. Una idea que falles vuelve a preguntarse primero, y cada opción te dice qué acertó o en qué falló:

Práctica que se adapta a ti

Practica esta lección

14 preguntas sobre 5 ideas de esta lección. Cada respuesta se explica al momento, y lo que aciertas se guarda en este navegador.

  1. Pregunta 1 de 14 ¿Qué significa "most recent call last" al principio de un traceback?

    Elige una respuesta.

    Ver la respuesta: pregunta 1 de 14

    Respuesta: Los marcos van desde la primera llamada hasta la línea que falló, que va la última

    Python imprime las llamadas en el orden en que se hicieron, así que la más reciente, la línea que falló, va la última, justo encima de la excepción. Por eso un traceback se lee de abajo arriba.

  2. Pregunta 2 de 14 ¿Qué imprime bill.py en la salida estándar antes de su traceback?

    ¿Qué imprime este programa? Elige una respuesta.

    prices = {"tea": 30, "toast": 45, "coffee": 60}
    
    
    def line_total(item, quantity):
        return prices[item] * quantity
    
    
    def bill(order):
        total = 0
        for item, quantity in order:
            total += line_total(item, quantity)
        return total
    
    
    print("First bill:", bill([("tea", 2), ("toast", 1)]))
    print("Second bill:", bill([("tea", 1), ("cofee", 2)]))
    Ver la respuesta: pregunta 2 de 14

    Respuesta: imprime

    First bill: 105

    La línea 15 imprime la primera cuenta, 105, antes de que la línea 16 empiece la segunda, cuya consulta falla. El traceback va a la salida de errores estándar.

  3. Pregunta 3 de 14 Los cuatro últimos marcos de un traceback están en …/lib/python3.14/json/decoder.py y __init__.py. ¿Dónde miras primero?

    Elige una respuesta.

    Ver la respuesta: pregunta 3 de 14

    Respuesta: En el último marco de tu propio archivo, la línea que llamó a json.loads(), y en lo que le pasó

    Cuando los últimos marcos están en código de otros, busca el último marco de tu propio archivo: esa línea llamó a la biblioteca, y lo que le pasó suele ser lo que está mal, como las comillas simples de bad_json.py.

  4. Pregunta 4 de 14 Un IndentationError detiene un archivo. ¿Qué tipo de error es, y cuándo informa Python de él?

    Elige una respuesta.

    Ver la respuesta: pregunta 4 de 14

    Respuesta: Un tipo de SyntaxError, del que se informa antes de que se ejecute nada del archivo

    IndentationError es una subclase de SyntaxError. Como todo error de gramática, se detecta mientras Python compila el archivo entero, así que no se ejecuta nada.

  5. Pregunta 5 de 14 ¿Por qué el informe de un SyntaxError no tiene la línea "Traceback (most recent call last)"?

    Elige una respuesta.

    Ver la respuesta: pregunta 5 de 14

    Respuesta: No hubo ninguna llamada, porque el archivo nunca empezó a ejecutarse

    La cadena de llamadas es lo que introduce "Traceback (most recent call last)". Un archivo que no se puede compilar nunca se ejecuta, así que el informe muestra solo el archivo, la línea, una marca y el mensaje.

  6. Pregunta 6 de 14 ¿Qué excepción lanza "3" + 4?

    Elige una respuesta.

    Ver la respuesta: pregunta 6 de 14

    Respuesta: TypeError

    Lo dice el mensaje: can only concatenate str (not "int") to str. Decide qué querías decir, int("3") + 4 o "3" + str(4).

  7. Pregunta 7 de 14 average = sum(marks) / len(marks) lanza ZeroDivisionError. ¿Qué compruebas primero?

    Elige una respuesta.

    Ver la respuesta: pregunta 7 de 14

    Respuesta: Si marks puede estar vacía, porque entonces len(marks) es 0

    Mira qué puede ser 0 en el divisor. Las cuentas y las longitudes son las sospechosas habituales: una lista vacía no tiene media, y el código tiene que decidir qué hacer cuando no hay notas.

  8. Pregunta 8 de 14 Un script guardado como json.py se detiene con AttributeError: module 'json' has no attribute 'loads' y una sugerencia de que consideres renombrarlo. ¿Cómo se arregla?

    Elige una respuesta.

    Ver la respuesta: pregunta 8 de 14

    Respuesta: Renombrar el archivo, por ejemplo a settings_check.py, para que import json encuentre el módulo de la biblioteca estándar

    Un archivo con el nombre de un módulo que importas oculta ese módulo. Python 3.13 y posteriores lo dicen en el mensaje: renombra el archivo, e import json vuelve a encontrar la biblioteca estándar.

  9. Pregunta 9 de 14 ¿Desde qué versión de Python señalan las marcas ~ y ^ la parte exacta de una línea que falló?

    Elige una respuesta.

    Ver la respuesta: pregunta 9 de 14

    Respuesta: 3.11

    Python 3.11 añadió las marcas ~ y ^ (PEP 657), que señalan la parte de una línea larga que falló, como la consulta prices[item] en bill.py.

  10. Pregunta 10 de 14 ¿Qué imprime Python 3.13 para stock[["tea", "toast"]] = 2?

    Elige una respuesta.

    Ver la respuesta: pregunta 10 de 14

    Respuesta: TypeError: unhashable type: 'list'

    Las dos versiones rechazan una lista como clave de un dict con TypeError. Python 3.14 añade lo que estabas haciendo, cannot use 'list' as a dict key, al antiguo unhashable type: 'list'.

  11. Pregunta 11 de 14 En el intérprete, ¿qué llamada muestra la documentación de la función integrada len?

    Elige una respuesta.

    Ver la respuesta: pregunta 11 de 14

    Respuesta: help(len)

    help(len) imprime la documentación de len, su firma y lo que devuelve. issubclass(KeyError, LookupError) te dice a qué tipo de error más amplio pertenece una excepción.

  12. Pregunta 12 de 14 ¿Qué es un ejemplo mínimo?

    Elige una respuesta.

    Ver la respuesta: pregunta 12 de 14

    Respuesta: El programa más pequeño que todavía muestra el error, hecho borrando lo que el error no necesita

    Copia el programa y borra todo lo que no hace falta para que ocurra el error, hasta que queden unas pocas líneas, como hace minimal.py con el KeyError de bill.py.

  13. Pregunta 13 de 14 Antes de pegar código y un traceback en un foro o en un asistente, ¿qué deberías quitar?

    Elige todas las respuestas correctas.

    Ver la respuesta: pregunta 13 de 14

    Respuesta:

    • Tu nombre de usuario en las rutas de archivo
    • Contraseñas, claves de API y tokens
    • Datos personales, como nombres y direcciones en los datos

    Conserva la excepción, su mensaje y las líneas que importan; quita los secretos, los datos personales y las partes de las rutas que dicen quién eres.

  14. Pregunta 14 de 14 Tu programa se detiene con KeyError: 'cofee' en tu propia función line_total. ¿Qué búsqueda tiene más probabilidades de encontrar ayuda?

    Elige una respuesta.

    Ver la respuesta: pregunta 14 de 14

    Respuesta: Python KeyError dictionary lookup, sin cofee ni line_total

    Busca la última línea, sin los nombres y los valores propios de tu programa, y añade lo que hacía el código, como una consulta a un diccionario.

Preguntas de entrevista

Calentamiento (júnior): ¿cómo se lee un traceback de Python?

De abajo arriba. La última línea nombra la excepción y su mensaje, como KeyError: 'cofee', que dice qué salió mal. El marco de encima da el archivo, el número de línea y la función donde ocurrió, con la propia línea y marcas bajo la parte que falló. Los marcos más arriba son las llamadas que llevaron hasta allí, la más antigua primero, que es lo que significa “most recent call last”. La línea que falló no siempre es la que hay que arreglar: sigue el valor incorrecto hacia arriba por los marcos hasta donde se originó, y sáltate los marcos de dentro de las bibliotecas hasta el último de tu propio código. Un informe de SyntaxError no tiene cadena de llamadas, porque el archivo nunca empezó a ejecutarse.

Dos preguntas más difíciles parten de esta lección: un error lanzado en lo más hondo de una biblioteca, y un mismo error que dos versiones de Python describen de forma distinta. Piensa tu primer paso antes de abrir cada una:

Las respuestas modelo se abren con cualquier pase: 79 ₹ por 1 semana (2,99 US$), un solo pago que nunca se renueva.

  1. De júnior a nivel medio

    Una tarea nocturna se detiene con KeyError: 'cofee'. Los tres últimos marcos de su traceback están dentro de una biblioteca de precios que instalaste; tu propio código aparece más arriba. Un compañero quiere envolver la llamada a la biblioteca en try/except KeyError y usar un precio de 0. ¿Qué haces en su lugar, y por qué?

    Respuesta modelo, Pro. Las respuestas modelo se abren con cualquier pase; los precios están en el aviso de esta página. Primer paso y preguntas de seguimiento (en inglés)

  2. De júnior a nivel medio

    Una compañera guardó el script de los dados como random.py. Con Python 3.14 el error dice que considere renombrar random.py; en un servidor con Python 3.12 el mismo archivo informa de un partially initialized module, most likely a circular import. Explica qué pasa de verdad en los dos casos, y cómo evitarías que vuelva a ocurrir.

    Respuesta modelo, Pro. Primer paso y preguntas de seguimiento (en inglés)

Para recordar

  • Lee un traceback desde abajo: la excepción y su mensaje, después la línea que falló y después las llamadas de encima.
  • El error suele estar más arriba que la línea que falla: sigue el valor incorrecto hasta donde se originó, y sáltate los marcos de dentro de las bibliotecas.
  • Un SyntaxError significa que no se ejecutó nada; cuando la línea que se muestra parece correcta, busca antes un corchete o unas comillas sin cerrar.
  • Python 3.14 sugiere palabras clave mal escritas y explica las claves no hashables; las sugerencias Did you mean …? para nombres y atributos son más antiguas.
  • Desatáscate con la documentación y help(), un print() de los valores implicados y un ejemplo mínimo, y nunca pegues secretos en una pregunta.

Referencias

Herramientas relacionadas

Informar de un problema con esta lección (en inglés)

Respuestas rápidas y búsqueda de herramientas

Escribe para buscar herramientas o para obtener una respuesta rápida (en inglés), por ejemplo 18% of 2500. Usa las flechas arriba y abajo para recorrer los resultados, Intro para elegir y Escape para cerrar.