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

Variables y tipos

Todo programa necesita recordar cosas. Un cuestionario necesita el nombre del jugador. Un juego necesita la puntuación actual. Un script del clima necesita la ciudad que estás consultando. Python usa variables para esto: nombres que asocias a valores para poder usarlos a lo largo de tu programa.

Las variables son referencias con nombre a valores. Python asocia un nombre a un objeto en el lado derecho de = y te permite reasignarlo en cualquier momento. El tipo vive en el valor, no en el nombre.

En Python, una variable es una asociación de nombre (name binding): una referencia en un espacio de nombres que se resuelve a un objeto en tiempo de ejecución. Los objetos llevan tipos; los nombres no. Esto es tipado dinámico: el mismo nombre puede referenciar objetos de tipos completamente diferentes en distintas sentencias.

python
player_name = "Sofía"
score       = 0
city        = "Ciudad de México"

Tres líneas. Tres cosas que Python ahora recuerda. Usa cualquiera de esos nombres más adelante y Python te devolverá el valor.

Cada línea crea una asociación: el nombre a la izquierda se refiere al objeto a la derecha. Python evalúa primero el lado derecho, luego crea la asociación.

Cada asignación crea o reasocia un nombre en el espacio de nombres local del ámbito actual. Python evalúa completamente la expresión del lado derecho antes de que la asociación entre en efecto. El nombre no lleva información de tipo propia.

Almacenar un valor

El signo = confunde a casi todos los que vienen de la clase de matemáticas. En Python, = no significa "igual a". Significa almacenar este valor bajo este nombre. Léelo de izquierda a derecha:

python
city = "Ciudad de México"

city obtiene "Ciudad de México". Le estás diciendo a Python: recuerda "Ciudad de México" y etiquétalo como city.

Puedes reemplazar el valor de una variable en cualquier momento. Python simplemente usa el más reciente:

python
score = 0
score = 10   # score ahora es 10
score = 15   # score ahora es 15

= es asignación: asocia un nombre a un objeto en el ámbito actual. Una forma abreviada estándar para actualizar una variable es la asignación aumentada:

python
score = 0
score += 10   # igual que: score = score + 10
score *= 2    # igual que: score = score * 2

También puedes asociar varios nombres a la vez:

python
x, y, z = 1, 2, 3
a = b = 0        # ambos comienzan en cero

La asignación asocia un nombre a un objeto; no copia un valor dentro de un contenedor. Dos nombres pueden referenciar el mismo objeto:

python
a = "hello"
b = a
print(id(a) == id(b))   # True (mismo objeto en memoria)

b = "world"             # b se reasocia a un nuevo objeto
print(id(a) == id(b))   # False
print(a)                # sigue siendo "hello": reasociar b no afectó a a

id() devuelve la identidad del objeto (su dirección de memoria en CPython). Esta distinción entre asociación de nombre y copia importa más con objetos mutables como listas y diccionarios, que se cubren en capítulos posteriores.

Las anotaciones de tipo documentan los tipos esperados para herramientas de análisis estático. No tienen efecto en tiempo de ejecución:

python
name:  str   = "Sofía"
score: int   = 0
ratio: float = 0.85

Nombrar tus variables

Tú eliges el nombre. Python tiene unas pocas reglas estrictas, y la comunidad sigue convenciones que vale la pena adoptar desde el primer día. Los nombres claros hacen el código legible semanas después. Los nombres crípticos causan dolor.

Python impone un pequeño conjunto de reglas de sintaxis para identificadores. Más allá de eso, las convenciones de PEP 8 son el estándar de facto en todas las bases de código y herramientas de Python.

Las reglas de sintaxis para identificadores de Python son mínimas. Las convenciones de PEP 8 no las impone el intérprete, pero las asumen los linters, verificadores de tipos y toda base de código profesional de Python. Desviarse de ellas crea fricción.

Reglas que Python impone:

  • Solo letras, dígitos y guiones bajos. Sin espacios ni guiones.
  • Debe comenzar con una letra o un guion bajo, nunca con un dígito
  • Distingue entre mayúsculas y minúsculas: score, Score y SCORE son tres variables separadas

Convenciones que todos siguen (PEP 8):

CosaEstiloEjemplo
Variables y funcionessnake_caseuser_name, total_price
ConstantesUPPER_SNAKE_CASEMAX_RETRIES, BASE_URL
ClasesPascalCaseUserAccount, DataLoader
python
# nombres claros, legibles a simple vista
user_name    = "Sofía"
total_price  = 49.99
is_logged_in = True
MAX_RETRIES  = 3

# te arrepentirás de estos en menos de una hora
x   = "Sofía"
tp  = 49.99
b   = True

Una trampa que vale la pena conocer pronto: no nombres una variable igual que un built-in de Python como list, input, type o print. Python lo permite, pero romperás silenciosamente el built-in durante el resto de ese ámbito y los errores resultantes son difíciles de rastrear.

No sombrees los built-ins de Python. Asignar a list, type, input, print o str sobrescribe el built-in durante el resto de ese ámbito sin ninguna advertencia. Es un error silencioso que puede ser doloroso de encontrar.

UPPER_SNAKE_CASE es una convención, no se impone. Python no te impedirá reasignar MAX_RETRIES = 99 más adelante. Es una señal para otros desarrolladores, nada más.

Sombrear un built-in crea una asociación local que tiene precedencia sobre el built-in en el orden normal de búsqueda de nombres. El built-in sigue siendo accesible mediante builtins.print y demás, pero el nombre sombreador lo oculta en el uso normal. UPPER_SNAKE_CASE no tiene aplicación a nivel de lenguaje. Para garantías genuinas de inmutabilidad que las herramientas puedan verificar, typing.Final en una anotación es el enfoque estándar.

Qué puedes almacenar

Python tiene cuatro tipos que usarás en casi todos los programas. Python deduce qué tipo quieres decir por cómo escribes el valor. Nunca declaras un tipo explícitamente.

Python infiere el tipo a partir de la sintaxis del literal. Estos cuatro tipos cubren el espacio fundamental de valores; todo lo demás en el lenguaje se construye sobre ellos.

Los cuatro tipos primitivos de Python se asignan a objetos distintos en tiempo de ejecución, con diferentes diseños de memoria, características de precisión y semánticas de operación. El tipo lo determina el objeto, no el nombre.

Texto (str)

Cualquier texto va entre comillas, simples o dobles. Las comillas le dicen a Python que te refieres a caracteres literales, no a un nombre de variable. Una vez creada, una cadena no puede cambiarse en su lugar. El capítulo Cadenas cubre todo lo que puedes hacer con ellas.

python
player_name = "Sofía"
city        = "Ciudad de México"
message     = 'Juego terminado'

Si tu texto contiene un apóstrofo, usa comillas dobles para evitar tener que escaparlo:

python
note = "It's a great day"
note = 'It\'s a great day'   # mismo resultado, usando un escape

Las cadenas contienen cualquier texto entre comillas simples o dobles. Son inmutables: ninguna operación modifica una cadena en su lugar; cada transformación devuelve una nueva. Esto importa para el rendimiento: usar + repetidamente dentro de un bucle crea un nuevo objeto de cadena en cada paso. El capítulo Cadenas cubre la alternativa eficiente.

python
player_name = "Sofía"
city        = "Ciudad de México"
note        = "It's a great day"

str es una secuencia inmutable de puntos de código Unicode, no de bytes. len("café") es 4, no 5. La inmutabilidad hace que las cadenas sean hashables: válidas como claves de diccionario y miembros de conjuntos. CPython internaliza cadenas cortas que parecen identificadores; dos variables asignadas al mismo literal corto a menudo comparten un único objeto en memoria. Ambos estilos de comillas producen objetos idénticos.

python
player_name = "Sofía"
city        = "Ciudad de México"
note        = "It's a great day"

Números enteros (int)

Los números enteros se escriben sin comillas ni punto decimal. Python los llama integers. Pueden ser tan grandes como necesites; Python maneja números arbitrariamente grandes sin ningún esfuerzo especial de tu parte.

python
score      = 0
age        = 28
population = 8_100_000_000   # los guiones bajos son solo para legibilidad

Los enteros se escriben sin comillas ni puntos decimales. Los enteros de Python son de precisión arbitraria: crecen para contener cualquier valor, a diferencia de los enteros de tamaño fijo de 32 o 64 bits en C o Java. Los guiones bajos en literales numéricos son cosméticos e ignorados por Python.

python
score      = 0
age        = 28
population = 8_100_000_000

int en Python es de precisión arbitraria: el objeto asigna memoria adicional a medida que el valor crece, limitado solo por la RAM disponible. CPython almacena en caché los enteros pequeños de -5 a 256 como singletons; id(1) == id(1) siempre es True. Fuera de ese rango, cada literal crea un objeto distinto. Por eso is da resultados poco fiables para comparaciones de enteros; usa siempre ==.

python
score      = 0
age        = 28
population = 8_100_000_000

Números decimales (float)

Cualquier número con un punto decimal es un float. Funcionan como se espera para la mayoría de los cálculos. Una cosa que debes saber: algunos valores decimales no pueden almacenarse exactamente en binario, por lo que puedes obtener un pequeño error de redondeo:

python
price       = 4.99
temperature = 36.6

0.1 + 0.2   # 0.30000000000000004

Para el trabajo cotidiano rara vez importa. Para cálculos financieros donde cuentan las fracciones de centavo, Python tiene un módulo decimal que lo maneja correctamente. Eso se cubre en el capítulo Números.

Cualquier número con un punto decimal se convierte en un float. Los floats de Python son IEEE 754 binary64: 64 bits con aproximadamente 15-17 dígitos decimales significativos de precisión. El problema conocido: 0.1 + 0.2 es 0.30000000000000004. No es un error de Python; es una consecuencia de la representación binaria. Para cálculos financieros donde importan los decimales exactos, el módulo decimal de Python es la herramienta correcta, cubierta en el capítulo Números.

python
price       = 4.99
temperature = 36.6

float se asigna al double de C: IEEE 754 binary64, mantisa de 53 bits, precisión relativa de 2^-52 ≈ 2.2e-16. Las fracciones cuyos denominadores tienen factores primos distintos de 2 (como 1/10 = 1/(2×5)) son no terminantes en binario y no pueden almacenarse exactamente. Para aritmética decimal exacta, decimal.Decimal de Python usa base 10 de precisión arbitraria. Para aritmética racional exacta, fractions.Fraction almacena pares numerador/denominador. Ambos están en la biblioteca estándar, cubiertos en el capítulo Módulos.

python
price       = 4.99
temperature = 36.6

Verdadero o falso (bool)

Algunas cosas están simplemente encendidas o apagadas. Python usa booleans para esto: exactamente dos valores, True y False. Parecen menores en esta etapa, pero cada condición y bifurcación en tu programa funciona con un booleano.

python
is_logged_in = True
has_errors   = False

Python también trata ciertos valores como si fueran False cuando se usan en una condición: 0, 0.0, "" y None (el "ningún valor aquí" de Python) se comportan todos como False. Todo lo demás se comporta como True. Esto se vuelve útil en el capítulo Flujo de control.

bool contiene exactamente True o False. Lo devuelven las comparaciones y lo consumen las condiciones. Python tiene un conjunto más amplio de valores verdaderos (truthy) y falsos (falsy): los valores cero, los contenedores vacíos y None son falsy; todo lo demás es truthy. Un detalle útil: bool es una subclase de int, por lo que True + True se evalúa como 2.

python
is_logged_in = True
has_errors   = False

bool es subclase de int. True y False son singletons con valores enteros 1 y 0 respectivamente. Valores falsy: valores cero (0, 0.0), secuencias y mapeos vacíos ("", [], (), {}), None y False. Todo lo demás es truthy. Los objetos personalizados controlan esto mediante __bool__ o __len__. isinstance(True, int) es True, lo que importa en código de verificación de tipos genérico.

python
is_logged_in = True
has_errors   = False

Verificar y convertir tipos

Cuando no estés seguro de qué tipo es un valor, type() te lo dice. Para verificar si un valor es de un tipo específico, isinstance() es la herramienta más confiable:

python
print(type("hello"))   # <class 'str'>
print(type(42))        # <class 'int'>
print(type(3.14))      # <class 'float'>
print(type(True))      # <class 'bool'>

isinstance(42, int)    # True
isinstance("hi", str)  # True

type() devuelve el tipo exacto de un objeto. Para verificación de tipos en tu propio código, se prefiere isinstance(): maneja la herencia, cosa que las comparaciones con type() no hacen.

python
print(type(42))          # <class 'int'>
isinstance(True, int)    # True   (bool es una subclase de int)
type(True) == int        # False  (coincidencia exacta, sin subclases)

type(x) devuelve el objeto tipo de x. isinstance(x, T) recorre el MRO (x.__class__.__mro__), manejando relaciones de subclase que las comparaciones con type() pasan por alto. El caso práctico: isinstance(True, int) es True porque bool es subclase de int; type(True) == int es False porque es una verificación exacta de identidad. Usa isinstance() para guardas de tipo en código de producción.

python
isinstance(True, int)    # True
type(True) == int        # False

Python no mezcla tipos automáticamente. Concatenar una cadena y un número genera un TypeError:

python
score = 42
print("Your score is " + score)        # TypeError
print("Your score is " + str(score))   # funciona

Convierte explícitamente usando el nombre del tipo como una función:

LlamadaResultado
str(42)"42"
int(3.9)3 (trunca, no redondea)
float("3.14")3.14
int("3.14")ValueError: no se puede convertir una cadena decimal a int directamente
int(float("3.14"))3 (convertir a float primero, luego a int)
bool(0) / bool("")False

En la práctica

Los cuatro tipos trabajando juntos en un pequeño script. Las líneas de salida usan f-strings para incrustar valores en el texto: pon f antes de la comilla de apertura y envuelve cualquier variable en {}. Python lo reemplaza con el valor real de la variable. Las aprenderás correctamente en el próximo capítulo.

python
player_name = "Sofía"
level       = 3
accuracy    = 0.94
is_premium  = True

print(f"{player_name} is on level {level} with {accuracy:.0%} accuracy.")
print(f"Premium account: {is_premium}")

Los tipos importan porque level + 1 funciona y player_name + 1 no. Cada variable contiene exactamente una clase de cosa; Python no las mezclará silenciosamente por ti.

Un bloque de configuración realista con los cuatro tipos, las constantes separadas del estado en tiempo de ejecución. La sintaxis f"..." es un f-string: cualquier expresión dentro de {} se evalúa en tiempo de ejecución y se incrusta en la salida. Se cubre por completo en el capítulo Salida y entrada.

python
BASE_URL    = "https://api.example.com"
MAX_RETRIES = 3
DEBUG       = False

user_name     = "Sofía"
request_count = 0
last_response = None

request_count += 1
print(f"[{request_count}] {BASE_URL} | debug={DEBUG}")

None es el marcador estándar para "aún no hay valor". Su tipo es NoneType y se comporta como falsy en condiciones. Úsalo como valor predeterminado para variables que no son significativas hasta más tarde en el programa.

La misma configuración con anotaciones de tipo en línea. Las anotaciones son documentación para verificadores de tipos e IDEs; no tienen efecto en tiempo de ejecución:

python
BASE_URL:    str  = "https://api.example.com"
MAX_RETRIES: int  = 3
DEBUG:       bool = False

user_name:     str        = "Sofía"
request_count: int        = 0
last_response: str | None = None

str | None es la sintaxis de unión de Python 3.10: la variable contiene una cadena o None. En versiones anteriores, el equivalente es Optional[str] del módulo typing. La forma str | None es preferida en Python moderno cuando la versión mínima lo permite.