Skip to content
This page has been auto-translated and may contain errors.View in English

Salida y entrada

Dos herramientas que usarás desde la primera línea que escribas: print() muestra valores en la terminal, input() obtiene texto del usuario. Son simples, pero conocer su comportamiento te evita varias sorpresas al principio.

print() e input() son las funciones estándar de E/S de terminal en Python. Ambas son más configurables de lo que parecen a primera vista. print() acepta argumentos que controlan cómo se unen los valores y dónde termina la salida. input() siempre devuelve una cadena, lo que define cómo manejas cada valor que viene del usuario.

print() envuelve sys.stdout; input() envuelve sys.stdin. Ambos trabajan exclusivamente con texto, delegan la codificación al códec del flujo y, por defecto, almacenan la salida en buffer. La separación de stdout de stderr, y el control sobre el vaciado del buffer, importan en programas reales.

Cómo Python ejecuta tu código

Python ejecuta tu código de arriba hacia abajo, una línea a la vez, exactamente en el orden en que la escribiste. Sin saltos. El orden en que escribes las cosas es el orden en que se ejecutan. Siempre.

python
ciudad = "Ciudad de México"
print(ciudad)
print("Población: 9 millones")

ciudad se asigna primero. El primer print se ejecuta. El segundo print se ejecuta. Cada vez, en ese orden.

Esto importa porque no puedes usar una variable antes de haberla asignado. Python aún no la ha visto y lanzará un error:

python
print(pais)   # NameError: pais aún no está definido
pais = "México"

Ten esto en cuenta a medida que tus programas crezcan: cualquier cosa que uses debe estar definida antes de usarla.

Python usa ejecución secuencial: cada instrucción se evalúa en el momento en que se encuentra, en una sola pasada de arriba hacia abajo por el archivo. No hay un análisis previo del archivo completo. Referenciar un nombre antes de asignarlo lanza NameError exactamente en esa línea, no antes.

python
ciudad = "Ciudad de México"
print(ciudad)           # funciona: ciudad ya está vinculada
print(pais)             # NameError: aún no está asignada
pais = "México"

La regla es simple: las dependencias deben definirse antes de la línea que las usa.

El modelo de ejecución de Python es evaluación secuencial de una sola pasada. La resolución de nombres ocurre en el punto de evaluación, no en el momento del análisis sintáctico. El analizador construye bytecode sin resolver nombres, por eso NameError es una excepción en tiempo de ejecución y no un error de sintaxis. Python no tiene hoisting (a diferencia de var en JavaScript) ni declaraciones adelantadas (a diferencia de C). Un nombre está disponible en el momento en que se vincula; antes de eso, cualquier referencia lanza una excepción.

python
print(pais)   # NameError en tiempo de ejecución, no error de sintaxis
pais = "México"

Imprimiendo salida

print() es la forma en que Python te responde. Pásale cualquier valor y muestra ese valor. Convierte automáticamente a texto lo que le des.

print() convierte cada argumento a una cadena mediante str(), los une con un separador (un espacio por defecto), luego escribe el resultado seguido de un salto de línea en la salida estándar. Entender los valores por defecto facilita razonar sobre los argumentos opcionales.

La firma completa de print() es print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False). El colector *objects acepta cualquier número de argumentos posicionales y llama a str() sobre cada uno. sep y end controlan el formato; file redirige la salida a cualquier flujo escribible; flush fuerza el vaciado inmediato del buffer.

python
print("Hola")     # Hola
print(42)         # 42
print(3.14)       # 3.14
print(True)       # True

Múltiples valores

Puedes imprimir varios valores a la vez separándolos con comas. Python pone un espacio entre ellos por defecto. Cambia el separador con sep:

Múltiples argumentos posicionales se convierten cada uno con str() individualmente, luego se unen mediante sep. El sep por defecto es un solo espacio. Sobrescribirlo te permite producir salida formateada sin concatenación de cadenas:

Cada argumento posicional pasa por str() individualmente antes de la unión. La unión usa sep, luego se añade end, y todo se escribe en una sola llamada al flujo de salida. Sobrescribir sep es más limpio que construir la cadena manualmente:

python
nombre = "Sofía"
edad   = 28
print(nombre, edad)                     # Sofía 28
print("Nombre:", nombre)                # Nombre: Sofía
print("2024", "01", "15", sep="-")     # 2024-01-15
print("a", "b", "c", sep=", ")         # a, b, c

Controlando el final de línea

Cada llamada a print() termina con un salto de línea por defecto, así que la siguiente salida comienza en una línea nueva. Cambia eso con end. Establecer end="" hace que el siguiente print continúe en la misma línea:

El parámetro end reemplaza el salto de línea por defecto. Establécelo en "" para suprimir el salto de línea, en " " para mantenerte en la misma línea con un espacio, o en cualquier otra cadena. Combinado con sep, puedes producir la mayoría de los formatos de salida sin construir cadenas manualmente:

sep y end son argumentos solo por palabra clave con valores por defecto ' ' y '\n'. Establecer end="" es la forma estándar de imprimir una línea parcial y dejar que la siguiente llamada la continúe. Para salida en tiempo real, como indicadores de progreso o logs, flush=True fuerza el vaciado inmediato del buffer en lugar de esperar un salto de línea o el llenado del buffer.

python
print("Cargando", end="")
print("...")
# Cargando...

print("uno", end=" | ")
print("dos", end=" | ")
print("tres")
# uno | dos | tres

Formateando salida con f-strings

La forma más limpia de construir mensajes son las f-strings. Pon f antes de la comilla de apertura, luego envuelve cualquier variable o expresión entre llaves. Python la completa en tiempo de ejecución. Puedes poner cualquier valor, cálculo o llamada a método dentro de {}.

Las f-strings evalúan cualquier expresión dentro de {} en tiempo de ejecución e insertan el resultado como cadena. Dos puntos después del valor introducen una especificación de formato: una sintaxis compacta para controlar lugares decimales, alineación y formato numérico. Son más rápidas y más legibles que la concatenación, y no requieren llamadas explícitas a str().

Las f-strings (PEP 498) compilan cada {} a bytecode que llama a format(value, spec), que delega a value.__format__(spec). Cualquier clase que implemente __format__ controla su propia visualización dentro de una f-string. Los indicadores de conversión !r, !s, !a aplican repr(), str() o ascii() antes de la llamada a format. !r es el más útil: muestra comillas alrededor de las cadenas y hace visibles los caracteres invisibles.

python
nombre = "Sofía"
puntos = 980

# concatenación: torpe, requiere str() para números
print("Jugador: " + nombre + ", Puntos: " + str(puntos))

# f-string: legible, sin conversión manual
print(f"Jugador: {nombre}, Puntos: {puntos}")

Puedes poner cualquier expresión dentro de {}: aritmética, llamadas a métodos, especificaciones de formato:

python
precio    = 49.99
impuesto  = 0.2
total     = precio * (1 + impuesto)

print(f"Total: {total:.2f}")          # Total: 59.99
print(f"Nombre: {nombre.upper()}")    # Nombre: SOFÍA
print(f"2 + 2 = {2 + 2}")             # 2 + 2 = 4

La especificación de formato después de : controla cómo se muestra el valor:

python
ratio  = 0.8765
conteo = 1234567
etiqueta = "ingresos"

print(f"{ratio:.1%}")        # 87.7%
print(f"{conteo:,}")         # 1,234,567
print(f"{etiqueta:>12}")     # "    ingresos"

:.2f significa "dos decimales". Lo usarás constantemente para precios y medidas. Todo lo demás está ahí cuando lo necesites. Lo principal: cualquier cosa puede ir dentro de {}, no solo nombres de variables.

:.2f y :.0% cubren la mayoría de las necesidades de formateo. Los especificadores de alineación (>, <, ^) con un ancho producen salida tabular ordenada. El patrón general es {valor:[alineación][ancho][.precisión][tipo]}. Una vez que reconoces las partes, cualquier especificación es legible sin memorizar todas las combinaciones.

La cadena de especificación se pasa textualmente a value.__format__(spec). Los tipos integrados implementan el mini-lenguaje de formato en C. Las clases personalizadas pueden definir __format__ para aceptar cadenas de especificación arbitrarias. !r llama a repr() antes del formateo: f"{name!r}" convierte una cadena con espacios al final en un repr entre comillas, haciendo visibles los caracteres invisibles. Úsalo siempre que el valor de una variable se vea raro y necesites ver exactamente qué hay dentro.

Obteniendo entrada del usuario

input() pausa tu programa y espera a que el usuario escriba algo. Lo que escriba (y presione Enter) regresa como valor de retorno. La cadena entre paréntesis es el mensaje que ve el usuario.

python
nombre = input("¿Cuál es tu nombre? ")
print(f"¡Hola, {nombre}!")

input() siempre devuelve una cadena, sin importar lo que el usuario escriba. Escribe 42 y obtienes "42", no el número 42. Para hacer aritmética con ello, convierte explícitamente:

python
edad = int(input("¿Cuántos años tienes? "))
print(f"En diez años tendrás {edad + 10}.")

¿Qué pasa si el usuario escribe algo que no se puede convertir? Python lanza un ValueError. Manejar eso correctamente se cubre en el capítulo Archivos y excepciones.

input() escribe el prompt en la salida estándar, lee una línea de la entrada estándar, elimina el salto de línea final y devuelve el resultado como una cadena. No hay inferencia de tipos. Todo lo que viene de la terminal llega como texto; tú declaras qué tipo necesitas convirtiendo explícitamente en el límite.

python
nombre = input("¿Cuál es tu nombre? ")
edad   = int(input("¿Cuántos años tienes? "))

Este patrón (recibir texto, convertir al tipo que necesitas) se aplica en todas partes donde llegan datos externos. int(), float() y str() son las herramientas de conversión. Si la cadena no se puede convertir, Python lanza ValueError, cubierto en el capítulo Archivos y excepciones.

input() es una interfaz delgada: llama a sys.stdout.write(prompt), vacía stdout, lee una línea de sys.stdin, elimina el salto de línea final y devuelve el resultado como str. El retorno siempre es str por diseño: Python no tiene forma de inferir si "42" se pretendía como entero, flotante o caracteres literales. La conversión de tipos en el límite es explícita. Este es un patrón fundamental en la E/S de Python: todos los datos externos llegan como texto, y tu código declara el tipo en el punto de entrada.

python
nombre     = input("Ingresa tu nombre: ")
puntuacion = float(input("Ingresa tu puntuación (0.0 a 1.0): "))

print(f"Nombre:      {nombre!r}")      # !r revela cualquier espacio invisible
print(f"Puntuación:  {puntuacion:.1%}")

Escribiendo a stderr

Por defecto, print() escribe a la salida estándar: el flujo que aparece en la terminal y se canaliza hacia pipes. Python también tiene error estándar, un flujo separado para diagnósticos y advertencias. Se ven idénticos en una terminal pero son distintos: cuando canalizas la salida de un script hacia otro comando, solo stdout pasa. Stderr siempre llega a la terminal.

Escribir a stderr usa el argumento file de print(). Eso requiere importar sys, lo cual se cubre en el capítulo Módulos. Por ahora, saber que los dos flujos existen y por qué están separados es suficiente.

En la práctica

Un quiz que se personaliza a partir de la entrada del usuario:

python
nombre  = input("¿Cuál es tu nombre? ")
materia = input("¿Qué materia? ")

print(f"Bien, {nombre}. Iniciando tu quiz de {materia}.")
print("¡Buena suerte!")

Ambas entradas regresan como cadenas y van directamente a las f-strings. No se necesita conversión porque las estás usando como texto, no como números.

Un conversor de temperatura con salida tabular alineada:

python
celsius    = float(input("Temperatura en Celsius: "))
fahrenheit = celsius * 9 / 5 + 32

print(f"{'Celsius':>12} {'Fahrenheit':>12}")
print(f"{celsius:>12.1f} {fahrenheit:>12.1f}")

float() maneja tanto enteros como decimales del usuario. La especificación >12 mantiene las columnas alineadas independientemente de cuántos dígitos tengan los números. Prueba ingresando 100 y -40: la salida se mantiene ordenada en ambos casos.

Usar !r para revelar exactamente qué recibió Python, útil cuando la salida se ve mal:

python
nombre     = input("Ingresa tu nombre: ")
puntuacion = float(input("Ingresa tu puntuación (0.0 a 1.0): "))

print(f"Nombre:      {nombre!r}")
print(f"Puntuación:  {puntuacion!r}")
print()
print(f"Resultado: {nombre}: {puntuacion:.1%}")

{nombre} y {nombre!r} se muestran idénticamente cuando la entrada está limpia. La diferencia aparece cuando hay espacios al final u otros caracteres invisibles. Adquirir el hábito de !r durante la depuración hace que los valores inesperados sean visibles de inmediato.

Practica salida y entrada en PythonTrabaja con ejercicios prácticos sobre print, f-strings y entrada del usuario en el curso de Scrimba.Start the course →