En la lección anterior usaste nombres como precio o stock para guardar valores. Esos nombres son variables, y en esta lección las estudiamos a fondo: qué ocurre exactamente al asignar, qué nombres son válidos y cuáles recomienda la guía de estilo PEP 8, cómo asignar varios valores de golpe, cómo se expresan las constantes en Python y una primera aproximación a dos ideas que te acompañarán todo el curso: el ámbito de las variables y la diferencia entre reasignar y mutar. Nombrar y organizar bien los datos es la mitad del trabajo de programar; el sistema de Papyrus empezará a parecerse a un programa de verdad.
Contenido
- Qué es una variable y cómo funciona la asignación
- Reglas de nombres (lo que Python exige)
- Convenciones de nombres: PEP 8 y snake_case
- Asignación múltiple e intercambio de valores
- Constantes por convención
- Ámbito básico a nivel de script
- Mutabilidad vs reasignación (introducción conceptual)
Qué es una variable y cómo funciona la asignación
Una variable es un nombre asociado a un valor. Se crea con el operador de asignación =:
La forma correcta de leer tienda = "Papyrus" es: "el nombre tienda pasa a referirse al valor "Papyrus"". El orden importa: a la izquierda el nombre, a la derecha el valor. Al revés ("Papyrus" = tienda) es un error de sintaxis.
Un matiz que en Python es más literal que en otros lenguajes: la variable no es una caja que contiene el valor, sino una etiqueta que apunta al valor. El valor existe en memoria, y el nombre es una referencia hacia él:
flowchart LR
A["tienda"] --> V1["'Papyrus' (str)"]
B["precio_odisea"] --> V2["12.50 (float)"]
C["stock_odisea"] --> V3["4 (int)"]
Esta imagen de "etiquetas sobre valores" te será muy útil en el apartado final de la lección y, más adelante, con las listas del módulo 4.
Una vez creada, la variable se usa escribiendo su nombre:
Y puede reasignarse: apuntar a un valor nuevo, olvidando el anterior:
Es muy común reasignar una variable usando su propio valor actual:
Aquí no hay ninguna paradoja matemática: primero se evalúa la derecha (3 - 1 → 2) y después el nombre pasa a apuntar al resultado. Python ofrece atajos para estas operaciones, los operadores de asignación aumentada:
| Atajo | Equivale a | Uso típico en Papyrus |
|---|---|---|
x += n |
x = x + n |
llegar un pedido: stock += 10 |
x -= n |
x = x - n |
vender: stock -= 1 |
x *= n |
x = x * n |
duplicar un precio |
x /= n |
x = x / n |
aplicar mitad de precio |
Recuerda de la lección anterior: no confundas = (asignar) con == (comparar).
Por último, usar una variable que no existe todavía produce un error:
Las variables deben asignarse antes de usarse: los scripts se ejecutan de arriba abajo.
Reglas de nombres (lo que Python exige)
Python impone unas pocas reglas duras sobre los nombres de variables. Si las incumples, el programa ni siquiera arranca (SyntaxError):
- Solo letras, dígitos y guiones bajos (
_). Nada de espacios, guiones-ni símbolos. - No pueden empezar por un dígito:
2libroses inválido;libros2es válido. - No pueden ser palabras reservadas del lenguaje:
if,for,while,and,or,not,True,False,None,class,def,import,return... (hay 35; el REPL te las lista conhelp("keywords")). - Mayúsculas y minúsculas se distinguen:
precio,PrecioyPRECIOson tres variables distintas.
| Nombre | ¿Válido? | Motivo |
|---|---|---|
stock_odisea |
Sí | Letras y guion bajo |
libro2 |
Sí | El dígito no va al principio |
2libro |
No | Empieza por dígito |
stock-odisea |
No | El guion - es el operador resta |
precio libro |
No | No se permiten espacios |
class |
No | Palabra reservada |
título |
Sí (legal) | Python 3 admite tildes y ñ, pero evítalo (siguiente apartado) |
Convenciones de nombres: PEP 8 y snake_case
Además de las reglas obligatorias, existe la guía de estilo oficial de Python, PEP 8 (Python Enhancement Proposal 8), que recomienda cómo deberías escribir el código para que sea legible y homogéneo. Sus convenciones de nombres más relevantes ahora:
- Variables y funciones:
snake_case— todo en minúsculas, palabras separadas por guiones bajos:precio_odisea,total_venta,nombre_cliente. - Constantes:
MAYUSCULAS_CON_GUIONES:IVA_LIBROS,NOMBRE_TIENDA(las vemos enseguida). - Clases:
PascalCase(cada palabra con inicial mayúscula):Libro,ClienteHabitual— lo usarás en el módulo 5. - Evita nombres con tildes o
ñaunque sean legales, y evitalsola,Omayúscula sola oImayúscula sola (se confunden con1y0).
| Estilo | Ejemplo | Se usa para |
|---|---|---|
snake_case |
precio_con_iva |
variables y funciones |
MAYUSCULAS |
IVA_LIBROS |
constantes |
PascalCase |
LibroDeSegundaMano |
clases (módulo 5) |
camelCase |
precioConIva |
no se usa en Python (es de Java/JavaScript) |
Tan importante como el formato es la expresividad. Compara:
# Mal: ¿qué es cada cosa?
x = 12.50
y = 3
z = x * y
# Bien: el código se explica solo
precio_unitario = 12.50
unidades_vendidas = 3
total_venta = precio_unitario * unidades_vendidasAmbos fragmentos hacen lo mismo, pero el segundo puede leerlo (y mantenerlo) cualquiera sin adivinar. Regla práctica: el nombre debe decir qué contiene la variable, no cómo se calcula ni de qué tipo es.
Asignación múltiple e intercambio de valores
Python permite asignar varias variables en una sola línea, separando con comas ambos lados:
Es equivalente a tres asignaciones, pero más compacto cuando los valores están relacionados (aquí, los tres datos de una ficha de libro). Debe haber el mismo número de nombres que de valores, o Python lanza ValueError.
También puede asignarse el mismo valor a varios nombres:
Y la joya de la corona: el intercambio de valores (swap) sin variable auxiliar. En muchos lenguajes intercambiar dos variables requiere una tercera temporal; en Python:
estante_a = "La Odisea"
estante_b = "Hamlet"
# Ana reordena el escaparate: los libros cambian de estante
estante_a, estante_b = estante_b, estante_a
print(estante_a) # Hamlet
print(estante_b) # La OdiseaFunciona porque Python evalúa primero todo el lado derecho (con los valores antiguos) y luego asigna al izquierdo. Este mecanismo, llamado desempaquetado, dará mucho más juego con las tuplas del módulo 4.
Constantes por convención
Una constante es un valor que no debería cambiar durante la ejecución del programa: un tipo de IVA, el nombre de la tienda, un descuento fijo.
Aquí Python es peculiar: no tiene constantes reales. No existe una palabra clave que impida reasignar una variable. En su lugar, la comunidad usa una convención: los nombres en MAYUSCULAS_CON_GUIONES significan "esto es una constante, no la toques".
# Constantes del sistema de Papyrus (van al principio del script)
NOMBRE_TIENDA = "Papyrus"
IVA_LIBROS = 0.04 # 4% (ficticio, para los ejemplos)
DESCUENTO_SOCIO = 0.05 # 5% para clientes socios
# Uso normal
precio_base = 12.50
precio_final = precio_base * (1 + IVA_LIBROS)
print(f"{NOMBRE_TIENDA}: precio final {precio_final:.2f} euros")Puntos clave:
- Python no impedirá que escribas
IVA_LIBROS = 0.21más abajo; simplemente ningún programador respetable lo hace. Es un contrato entre humanos. - Las constantes se declaran al principio del script, agrupadas, para que quien lea el código encuentre en un solo lugar los valores de configuración.
- Ventaja enorme: si el IVA cambia, lo modificas en una línea, en lugar de buscar
0.04repartido por todo el programa. A los valores numéricos sueltos y repetidos por el código se les llama despectivamente números mágicos; las constantes son su antídoto.
Ámbito básico a nivel de script
El ámbito (scope) de una variable es la zona del programa donde ese nombre existe y puede usarse. Como todavía no escribimos funciones (llegan en el módulo 3), tus scripts trabajan en un único ámbito, llamado ámbito global del módulo, y las reglas son sencillas:
- Una variable existe desde la línea en que se asigna hasta el final del script.
- Usarla antes de esa línea produce
NameError. - En el REPL ocurre lo mismo: las variables viven desde que las defines hasta que cierras la sesión.
# ficha.py
print(NOMBRE_TIENDA) # NameError: aún no existe
NOMBRE_TIENDA = "Papyrus"
print(NOMBRE_TIENDA) # ahora sí: PapyrusDos consecuencias prácticas:
- Orden lógico: define primero (constantes y datos arriba), usa después. Un script bien organizado se lee de arriba abajo como una receta.
- Cuidado con reutilizar nombres: si llamas
precioa tres cosas distintas a lo largo del script, la variable irá cambiando de valor y el código será confuso. Mejor nombres específicos:precio_odisea,precio_hamlet.
Cuando lleguen las funciones verás que crean su propio ámbito local (variables que solo existen dentro de la función); de momento, quédate con la idea de que dónde defines una variable determina dónde puedes usarla.
Mutabilidad vs reasignación (introducción conceptual)
Terminamos con una distinción conceptual que evitará muchas confusiones futuras. Hay dos formas de que "algo cambie" en un programa:
| Concepto | Qué cambia | Ejemplo |
|---|---|---|
| Reasignación | La etiqueta pasa a apuntar a otro valor. El valor antiguo no se modifica. | stock = 5 y luego stock = 4 |
| Mutación | El valor mismo se modifica por dentro, sin cambiar de etiqueta. | Añadir un libro a una lista (módulo 4) |
Todos los tipos que conoces hasta ahora — int, float, str, bool, None — son inmutables: sus valores no pueden modificarse por dentro. Cuando haces stock = stock - 1, no estás "rebajando" el número 5; estás creando/obteniendo el número 4 y moviendo la etiqueta hacia él. El 5 sigue siendo 5, intocable.
Con las cadenas se ve muy claro:
titulo = "la odisea"
titulo.upper() # produce "LA ODISEA"... pero no cambia titulo
print(titulo) # la odisea (¡sigue igual!)
titulo = titulo.upper() # para "cambiarla" hay que REASIGNAR
print(titulo) # LA ODISEALas operaciones sobre tipos inmutables devuelven valores nuevos; si quieres conservar el resultado, reasigna.
¿Y la mutación? Aparecerá en el módulo 4 con las listas: una lista sí puede modificarse por dentro (añadir, quitar, reordenar elementos) sin reasignar la variable. Entonces la imagen de "etiquetas que apuntan a valores" será crucial, porque dos etiquetas pueden apuntar a la misma lista y los cambios se verán desde ambas. Por ahora basta con la idea:
- Reasignar = mover la etiqueta a otro valor (posible siempre).
- Mutar = cambiar el valor por dentro (solo con tipos mutables, que aún no hemos visto).
Errores Comunes y Consejos
NameError: name '...' is not defined: usas la variable antes de asignarla, o la has escrito con una errata (recuerda quePrecioyprecioson distintas).- Nombres crípticos:
p,x2,dato. Dentro de dos semanas ni tú sabrás qué eran. Invierte cinco segundos en un buen nombre; los recuperarás multiplicados. - camelCase en Python:
precioFinalfunciona, pero desentona con todo el ecosistema. En Python,snake_case:precio_final. - Machacar una constante: escribir
IVA_LIBROS = 0.21a mitad de script es legal pero rompe el contrato de las mayúsculas. Si un valor cambia durante la ejecución, es que no era una constante: nómbralo en minúsculas. - Sombras sobre nombres de Python: evita llamar a tus variables
print,str,type... Es legal, pero "tapa" la función original (print = 5haría queprint("hola")fallara el resto del script). - Esperar que
titulo.upper()cambietitulo: las cadenas son inmutables; el resultado hay que reasignarlo. - Consejo: cuando dudes si un nombre es bueno, léelo en una frase: "el
precio_unitariopor lasunidades_vendidasda eltotal_venta". Si la frase suena natural, los nombres son buenos.
Ejercicios
Ejercicio 1
Indica si cada nombre es inválido (Python da error), legal pero contrario a PEP 8, o correcto para una variable normal:
total-ventaTotalVentatotal_venta2do_libro_descuentofor
Ejercicio 2
Escribe un script para Papyrus que:
- Defina las constantes
NOMBRE_TIENDA = "Papyrus"yDESCUENTO_SOCIO = 0.05. - Cree con asignación múltiple en una sola línea las variables
titulo,precioystockcon los valores"El Quijote",15.90y8. - Simule la venta de 2 ejemplares a Luis (que es socio): actualice
stockcon un operador de asignación aumentada y calcule el total con el descuento aplicado. - Muestre con f-strings el stock restante y el total cobrado con dos decimales.
Ejercicio 3
Ana ha etiquetado mal dos libros y hay que intercambiar sus precios. Partiendo de estas variables, intercámbialos sin usar ninguna variable auxiliar y muestra el resultado:
Después, responde: tras ejecutar precio_odisea = 12.50, ¿se ha mutado el valor 9.95? ¿Por qué?
Soluciones
Solución 1
total-venta— inválido: el guion es el operador resta; Python lo lee comototal - venta.TotalVenta— legal pero contrario a PEP 8: es PascalCase, reservado por convención para clases.total_venta— correcto: snake_case perfecto.2do_libro— inválido: no puede empezar por dígito._descuento— legal: el guion bajo inicial es válido (por convención sugiere "uso interno", lo verás en el módulo 5); para una variable normal bastaríadescuento.for— inválido: palabra reservada.
Solución 2
# venta_socio.py
NOMBRE_TIENDA = "Papyrus"
DESCUENTO_SOCIO = 0.05
titulo, precio, stock = "El Quijote", 15.90, 8
# Venta de 2 ejemplares a Luis (socio)
unidades = 2
stock -= unidades
total = precio * unidades * (1 - DESCUENTO_SOCIO)
print(f"{NOMBRE_TIENDA}: vendidos {unidades} x {titulo}")
print(f"Stock restante: {stock}")
print(f"Total cobrado: {total:.2f} euros")stock -= unidades equivale a stock = stock - unidades; y (1 - DESCUENTO_SOCIO) es 0.95, es decir, pagar el 95% del importe.
Solución 3
precio_odisea = 9.95
precio_hamlet = 12.50
precio_odisea, precio_hamlet = precio_hamlet, precio_odisea
print(f"La Odisea: {precio_odisea:.2f} euros") # 12.50
print(f"Hamlet: {precio_hamlet:.2f} euros") # 9.95Python evalúa primero el lado derecho completo (12.50, 9.95, con los valores antiguos) y después lo asigna al izquierdo, logrando el intercambio en una línea.
Respuesta a la pregunta: no hay mutación. Los float son inmutables: 9.95 sigue existiendo tal cual; lo único que ha pasado es que la etiqueta precio_odisea ahora apunta a otro valor (12.50). Es una reasignación.
Conclusión
Ahora dominas la pieza central de cualquier programa: las variables como etiquetas que apuntan a valores, la asignación (simple, aumentada y múltiple), las reglas de nombres y las convenciones PEP 8 (snake_case para variables, MAYÚSCULAS para constantes), el ámbito básico de un script que se lee de arriba abajo, y la diferencia conceptual entre reasignar una etiqueta y mutar un valor. Papyrus ya tiene constantes de configuración y su primera venta con descuento a Luis.
Hasta ahora, todos los datos estaban escritos dentro del código. En la próxima lección, Entrada y Salida Básica, el programa cobrará vida: aprenderás a pedir datos al usuario con input(), a dar formato profesional a la salida y construirás el primer programa interactivo de Papyrus.
Curso de Programación en Python
Módulo 1: Introducción a Python
- Introducción a Python
- Configuración del Entorno de Desarrollo
- Sintaxis de Python y Tipos de Datos Básicos
- Variables y Constantes
- Entrada y Salida Básica
- Entornos Virtuales y Gestión de Paquetes
Módulo 2: Estructuras de Control
- Sentencias Condicionales
- Bucles: for y while
- Herramientas de Control de Flujo
- Comprensiones de Listas
Módulo 3: Funciones y Módulos
- Definición de Funciones
- Argumentos de Función
- Funciones Lambda
- Módulos y Paquetes
- Visión General de la Biblioteca Estándar
Módulo 4: Estructuras de Datos
Módulo 5: Programación Orientada a Objetos
Módulo 6: Manejo de Archivos
- Lectura y Escritura de Archivos
- Trabajo con Archivos CSV
- Manejo de Datos JSON
- Operaciones con Archivos y Directorios
Módulo 7: Manejo de Errores y Excepciones
- Introducción a las Excepciones
- Manejo de Excepciones
- Lanzamiento de Excepciones
- Excepciones Personalizadas
- Buenas Prácticas y Registro de Errores con logging
Módulo 8: Temas Avanzados
- Anotaciones de Tipos (type hints)
- Decoradores
- Generadores
- Administradores de Contexto
- Concurrencia: Hilos y Procesos
- Asyncio para Programación Asíncrona
Módulo 9: Pruebas y Depuración
- Introducción a las Pruebas
- Pruebas Unitarias con unittest
- Pruebas con pytest
- Desarrollo Guiado por Pruebas
- Técnicas de Depuración
- Uso de pdb para Depuración
Módulo 10: Desarrollo Web con Python
- Introducción al Desarrollo Web
- Fundamentos del Framework Flask
- Construcción de APIs REST con Flask
- Introducción a Django
- Construcción de Aplicaciones Web con Django
Módulo 11: Ciencia de Datos con Python
- Introducción a la Ciencia de Datos
- NumPy para Computación Numérica
- Pandas para Manipulación de Datos
- Matplotlib para Visualización de Datos
- Introducción al Aprendizaje Automático con scikit-learn
