Variables y tipos de datos en Python: la guía que ojalá hubiera tenido cuando empecé

📅 Actualizado en marzo 2026 📊 Nivel: Principiante ⏱️ 22 min de lectura

Cuando empecé con Python, pensaba que las variables eran «cajitas donde guardas cosas». Es una metáfora cómoda, pero resulta que está mal, y esa imprecisión inicial me causó varios errores que no entendía. En esta lección vamos a ver las variables y los tipos de datos de la manera correcta, y de paso aprenderemos algo sobre cómo Python gestiona la memoria que muchos tutoriales para principiantes nunca explican.

Si vienes de Java, C# o cualquier lenguaje de tipado estático, prepárate para que algunas cosas te sorprendan. Si es tu primer lenguaje, mejor todavía: aprenderás desde el principio cómo funciona Python de verdad, sin malos hábitos importados de otros sitios.

🏷️ ¿Qué es una variable? La metáfora de la caja (y por qué está mal)

La explicación clásica dice: «una variable es como una caja donde guardas un valor». Intuitivo, fácil de visualizar. Pero Python no funciona así exactamente, y entender la diferencia te va a salvar de más de un quebradero de cabeza.

En Python, una variable es más bien una etiqueta que apunta a un objeto en memoria. El objeto tiene el valor y el tipo. La variable es simplemente el nombre que usas para referirte a ese objeto. Ejemplo:

etiquetas.py
# Python crea el objeto 42 en memoria y "x" apunta a él
x = 42

# Ahora "y" apunta al MISMO objeto 42, no a una copia
y = x

# Verificar que apuntan al mismo objeto
print(x is y)        # True — mismo objeto en memoria
print(id(x))         # 140234567890 (dirección en memoria)
print(id(y))         # 140234567890 — ¡la misma!

# Cuando reasignas x, NO modificas el 42 original.
# Simplemente x ahora apunta a un nuevo objeto 100.
x = 100
print(y)             # 42 — y sigue apuntando al 42 original

¿Por qué importa esto? Porque cuando haces y = x no estás creando una copia del valor — estás haciendo que dos etiquetas apunten al mismo objeto. Para los tipos básicos (int, float, str, bool) esto no causa problemas porque son inmutables: no puedes modificar el objeto, solo puedes apuntar a otro. Pero cuando lleguemos a listas y diccionarios, este comportamiento te va a importar mucho.

💡 La función id()
id(variable) devuelve el identificador único del objeto en memoria (básicamente su dirección). Es una herramienta excelente para entender qué está pasando cuando trabajas con variables. No la usarás en producción, pero para aprender es oro.

🧩 Los 5 tipos de datos fundamentales

Python tiene muchos tipos de datos, pero cuando empiezas, solo necesitas conocer cinco. Son los que usarás el 95% del tiempo en las primeras semanas:

Infografía: los 5 tipos de datos fundamentales de Python — int, float, str, bool y NoneType con ejemplos y operaciones
Los 5 tipos de datos fundamentales de Python. Cada uno con sus ejemplos de uso y las operaciones que acepta. Infografía: Ciberaula.

Vamos a ver cada uno en detalle, con sus peculiaridades y las trampas que pilla a los principiantes.

🔢 int: números enteros sin sorpresas

El tipo int representa números enteros: positivos, negativos y el cero. La gran diferencia con otros lenguajes es que en Python los enteros no tienen límite de tamaño. En Java un int se desborda si supera ~2.100 millones. En Python puedes calcular factoriales astronómicos sin problema:

enteros.py
# Enteros normales
edad = 28
temperatura = -5
contador = 0

# Literales con separador de miles (Python 3.6+)
poblacion_esp = 47_431_256    # más legible que 47431256
distancia_km  = 1_000_000

# Python maneja enteros arbitrariamente grandes
factorial_100 = 1
for i in range(1, 101):
    factorial_100 *= i
print(len(str(factorial_100)), "dígitos")  # 158 dígitos — sin desbordamiento

# Bases numéricas
hex_val  = 0xFF      # hexadecimal → 255
bin_val  = 0b1010    # binario → 10
oct_val  = 0o17      # octal → 15

print(hex_val, bin_val, oct_val)  # 255 10 15

El separador de miles con guión bajo (47_431_256) es uno de esos pequeños detalles de Python que me encantan. No afecta al valor, pero hace el código mucho más legible cuando trabajas con números grandes. Algo que Java y JavaScript no tienen nativamente.

📌 Comprobar el tipo de cualquier valor
La función type(valor) devuelve el tipo de cualquier objeto. Es tremendamente útil mientras aprendes: type(42) devuelve <class 'int'>, type("hola") devuelve <class 'str'>. Úsala siempre que no estés seguro de qué tipo tiene una variable.

🔣 float: decimales y sus trampas

El tipo float representa números con punto decimal. Internamente usa el estándar IEEE 754 de doble precisión, que es el mismo que usan Java, C, JavaScript y prácticamente todos los lenguajes modernos. Y eso implica una trampa que pilla a todo el mundo:

floats.py
# Floats normales
precio   = 9.99
pi       = 3.14159
altura   = 1.72

# La trampa clásica del punto flotante
print(0.1 + 0.2)          # 0.30000000000000004 ← ¡no es 0.3!
print(0.1 + 0.2 == 0.3)   # False ← esto te va a sorprender

# La forma correcta de comparar floats
import math
print(math.isclose(0.1 + 0.2, 0.3))  # True ← así se hace

# Para dinero: usar el módulo decimal
from decimal import Decimal
precio_exacto = Decimal("9.99")
iva_exacto    = Decimal("0.21")
print(precio_exacto * iva_exacto)  # 2.0979 — exacto

# Notación científica
muy_grande = 1.5e10    # 15000000000.0
muy_pequeno = 2.5e-4  # 0.00025

El tema de 0.1 + 0.2 == 0.3 siendo False es el bug más famoso de la informática que no es un bug. Es así en todos los lenguajes que usan IEEE 754, y eso incluye prácticamente todos. La razón: 0.1 en binario es un número periódico (como 1/3 en decimal), y la representación se trunca, generando un pequeño error.

⚠️ Nunca uses float para dinero
Si estás construyendo algo que maneja dinero real, usa el módulo decimal de la librería estándar. Los errores de punto flotante en aplicaciones financieras pueden acumularse y generar discrepancias reales. Decimal("9.99") en lugar de 9.99.
Pantalla de portátil mostrando código Python con resaltado de sintaxis sobre fondo oscuro
Código Python con resaltado de sintaxis en editor de tema oscuro. Foto: Pexels (Stanislav Kondratiev).

📝 str: cadenas de texto y sus superpoderes

Las cadenas de texto (strings) en Python son una de sus partes más potentes. Un str es una secuencia inmutable de caracteres Unicode, lo que significa que puedes trabajar con cualquier idioma, emoji o símbolo sin configuración extra.

strings.py
# Tres formas de crear strings (todas equivalentes)
s1 = 'comillas simples'
s2 = "comillas dobles"
s3 = """comillas triples
   para texto
   multilínea"""

# Strings con caracteres especiales
ruta = 'C:\\Users\\Ana\\documentos'    # \\ para barra invertida
ruta2 = r'C:\Users\Ana\documentos'    # raw string, más limpio
nueva_linea = "primera línea\nsegunda línea"

# Acceso por índice — los índices empiezan en 0
nombre = "Python"
print(nombre[0])     # P — primer carácter
print(nombre[-1])    # n — último carácter
print(nombre[1:4])   # yth — slice (del índice 1 al 3)
print(nombre[:3])    # Pyt — desde el principio hasta el 2
print(nombre[::-1])  # nohtyP — invertir la cadena

# Métodos más útiles
frase = "  Hola, Mundo!  "
print(frase.strip())          # "Hola, Mundo!" — quita espacios
print(frase.lower())          # "  hola, mundo!  "
print(frase.upper())          # "  HOLA, MUNDO!  "
print(frase.strip().split(","))  # ["Hola", " Mundo!"]
print("Python" in frase)     # False
print(frase.replace("Mundo", "Python"))  # "  Hola, Python!  "

Una cosa que me sorprendió cuando empecé: en Python puedes acceder a los caracteres de una cadena con índices negativos. nombre[-1] es el último carácter, nombre[-2] el penúltimo, y así. Parece un detalle menor, pero cuando quieres el último elemento de algo es mucho más elegante que nombre[len(nombre)-1].

MétodoQué haceEjemploResultado
.strip()Elimina espacios en los extremos" hola ".strip()"hola"
.lower() / .upper()Convierte a minúsculas / mayúsculas"PYTHON".lower()"python"
.split(sep)Divide en lista usando separador"a,b,c".split(",")["a","b","c"]
.replace(a, b)Reemplaza todas las ocurrencias"hola".replace("l","r")"hora"
.startswith(s)¿Empieza por s?"Python".startswith("Py")True
.find(s)Posición de la primera aparición"Python".find("th")2
.count(s)Cuántas veces aparece s"banana".count("a")3
.join(lista)Une lista en cadena con separador"-".join(["a","b","c"])"a-b-c"
📌 Los strings son inmutables
No puedes modificar un carácter de un string directamente. nombre[0] = "J" da error. Para "modificar" un string, creas uno nuevo. Los métodos como .replace() no modifican el original: devuelven un nuevo string. Esto es una fuente de errores frecuente: olvidar guardar el resultado de un método.

⚖️ bool: verdadero, falso y los valores «truthy»

El tipo bool solo tiene dos valores posibles: True y False (con mayúscula inicial, como en inglés). Los usarás constantemente en condiciones, bucles y lógica. Pero hay algo sobre Python que no es tan obvio: casi cualquier valor puede usarse en un contexto booleano, y tiene un comportamiento «truthy» o «falsy» predefinido.

booleanos.py
# Valores booleanos básicos
activo   = True
inactivo = False
print(type(activo))   # <class 'bool'>

# bool es subclase de int en Python
print(True  + 1)   # 2 — True vale 1
print(False + 1)   # 1 — False vale 0
print(True  * 5)   # 5

# Valores FALSY (se comportan como False en condiciones)
# 0, 0.0, "" (string vacío), [] (lista vacía), {} (dict vacío),
# None, y False. Todo lo demás es TRUTHY.
print(bool(0))      # False
print(bool(""))     # False
print(bool([]))     # False
print(bool(42))     # True
print(bool("hola")) # True
print(bool([1,2]))  # True

# Operadores lógicos
print(True and True)    # True
print(True and False)   # False
print(True or  False)   # True
print(not  True)        # False

Lo de que bool sea subclase de int es uno de esos detalles de Python que te sorprenden la primera vez. True + True + True es 3. Técnicamente correcto, aunque probablemente nunca lo uses así en producción. Pero es útil saber que sum([True, False, True, True]) devuelve 2 — contar cuántos valores son verdaderos en una lista.

⚠️ Cuidado con los valores falsy en condiciones
El código if nombre: es válido Python y significa «si nombre tiene algún valor». Pero cuidado: si nombre = 0 o nombre = "" o nombre = [], la condición falla aunque la variable «existe». Si quieres verificar exactamente que algo es False (y no otro valor falsy), usa if variable is False: en lugar de if not variable:.

∅ None: el valor que significa «nada»

None es el valor que representa la ausencia de valor. No es cero, no es una cadena vacía, no es False. Es literalmente «no tengo nada aquí». Lo verás constantemente: las funciones que no devuelven nada devuelven None implícitamente, y es el valor por defecto para inicializar variables que aún no tienen dato.

none_ejemplos.py
# None: ausencia de valor
resultado = None
usuario_activo = None
print(type(None))  # <class 'NoneType'>

# Las funciones sin return devuelven None
def saludar():
    print("Hola")
    # no hay return

valor = saludar()    # imprime "Hola"
print(valor)         # None

# Comprobar None: usar "is", no "=="
if resultado is None:
    print("No hay resultado todavía")

if resultado is not None:
    print(f"El resultado es: {resultado}")

# La diferencia entre None, 0 y ""
print(None  == 0)       # False — None no es cero
print(None  == "")      # False — None no es string vacío
print(None  == False)   # False — None no es False
print(None  is None)    # True  — None solo es None

Una regla que aprendí a base de errores: siempre comprueba None con is None, no con == None. Técnicamente == None funciona casi siempre, pero hay casos donde objetos personalizados sobreescriben el operador == y pueden confundir la comparación. is None comprueba identidad de objeto, y como None es un singleton (existe una sola instancia en todo el programa), siempre es seguro.

🔄 Tipado dinámico: lo que hace diferente a Python

En lenguajes como Java o C#, cuando declaras una variable, le asignas un tipo permanente: int edad = 28;. Ese tipo no puede cambiar. Python funciona de manera radicalmente diferente: el tipo lo tiene el objeto, no la variable. La variable puede apuntar a cualquier tipo en cualquier momento.

Infografía: el tipado dinámico en Python — una misma variable apunta sucesivamente a un int, un str y un bool
Tipado dinámico: la variable es solo una etiqueta que puede apuntar a distintos tipos de objetos. Infografía: Ciberaula.
tipado_dinamico.py
# En Python, la misma variable puede cambiar de tipo
x = 42
print(type(x))    # <class 'int'>

x = "hola"
print(type(x))    # <class 'str'>

x = [1, 2, 3]
print(type(x))    # <class 'list'>

# Esto es perfectamente válido (aunque no es buen estilo)
variable = True
variable = 3.14
variable = "ahora soy un string"

# isinstance() para comprobar el tipo de forma más pythónica
numero = 42
print(isinstance(numero, int))          # True
print(isinstance(numero, (int, float)))  # True — comprueba varios tipos
print(isinstance(numero, str))          # False

El tipado dinámico tiene ventajas (código más corto, más flexible) e inconvenientes (los errores de tipo aparecen en ejecución, no en compilación). Por eso Python 3.5+ añadió los type hints, que permiten anotar los tipos esperados sin hacer que el lenguaje sea estáticamente tipado. Los veremos en el módulo avanzado.

💡 type() vs isinstance()
Usa type(x) == int solo cuando necesites el tipo exacto. Usa isinstance(x, int) cuando quieras ser flexible con subclases. Por ejemplo, isinstance(True, int) devuelve True (porque bool es subclase de int), mientras que type(True) == int devuelve False. En la práctica, isinstance() es la forma más pythónica.
Programador trabajando con código en un portátil con varias pantallas en un escritorio moderno
Trabajando con Python en el día a día: entender los tipos de datos te ahorra muchos errores. Foto: Pexels (Mikhail Nilov).

🔄 Conversión de tipos: int(), float(), str(), bool()

Python no convierte tipos automáticamente (a diferencia de JavaScript, que lo hace incluso cuando no quieres). Si necesitas cambiar el tipo de un valor, tienes que hacerlo de forma explícita. Esto se llama type casting o conversión de tipos.

conversion_tipos.py
# str → int
texto_num = "42"
numero = int(texto_num)
print(numero + 8)          # 50 — ahora podemos operar

# str → float
precio_texto = "9.99"
precio = float(precio_texto)
print(precio * 1.21)       # 12.0879

# Número → str
edad = 28
mensaje = "Tengo " + str(edad) + " años"  # necesario para concatenar
print(mensaje)

# Mejor con f-strings (no necesitas str())
print(f"Tengo {edad} años")  # más limpio

# int → float (conversión implícita en operaciones)
resultado = 7 / 2            # 3.5 — Python lo convierte automáticamente
resultado2 = 7 // 2          # 3 — división entera, sigue siendo int

# float → int (PIERDE los decimales, no redondea)
print(int(3.9))              # 3, no 4 — trunca, no redondea
print(round(3.9))            # 4 — round() sí redondea

# Valores que NO se pueden convertir
try:
    int("hola")               # ValueError: invalid literal
except ValueError as e:
    print(f"Error: {e}")

# Conversión a bool (qué es truthy y qué es falsy)
print(bool(1))      # True
print(bool(0))      # False
print(bool(""))     # False
print(bool("x"))    # True
FunciónConvierteEjemploResultadoPuede fallar si...
int(x)→ enteroint("42")42El texto no es un entero válido
float(x)→ decimalfloat("3.14")3.14El texto no es un número válido
str(x)→ textostr(42)"42"Nunca falla
bool(x)→ booleanobool(0)FalseNunca falla
round(x, n)Redondea floatround(3.567, 2)3.57Nunca falla
⚠️ int() trunca, no redondea
int(3.9) devuelve 3, no 4. Siempre trunca hacia cero: int(-2.8) devuelve -2. Si quieres redondear al entero más cercano, usa round(). Si quieres redondear siempre hacia arriba, usa math.ceil(). Confundir esto genera errores sutiles que son difíciles de detectar.

✍️ Nombrar variables como un profesional

El nombre de una variable es una decisión importante. Un buen nombre hace que el código se lea casi como prosa; un mal nombre obliga a rastrear el código para entender qué hace. Estas son las convenciones de Python (definidas en el PEP 8, la guía de estilo oficial):

buenas_practicas.py
# ✅ snake_case para variables y funciones
nombre_usuario = "Ana"
precio_con_iva = 12.09
es_administrador = True
numero_intentos = 0

# ✅ UPPER_CASE para constantes
IVA_GENERAL     = 0.21
URL_BASE        = "https://api.ejemplo.com"
MAX_REINTENTOS  = 3

# ✅ Nombres descriptivos, no abreviaciones crípticas
# MAL:
n = "Ana"
p = 9.99
x1 = True

# BIEN:
nombre = "Ana"
precio = 9.99
esta_activo = True

# ✅ Variables booleanas con prefijo "es_", "tiene_", "puede_"
es_valido       = True
tiene_permisos  = False
puede_editar    = True

# ❌ Evitar
# - nombres de una letra (excepto i, j, k en bucles)
# - nombres genéricos como "data", "info", "temp" (sin contexto)
# - mezclar español e inglés: precio_price, nombre_name
# - abreviaciones que no sean estándar: usr, msg_txt, cfg

Una regla que me ayudó mucho al principio: si necesitas un comentario para explicar qué es una variable, probablemente el nombre está mal. d = 7 + comentario «número de días» es peor que dias_semana = 7 sin comentario. El nombre es la documentación.

EstiloCuándo usarloEjemplo
snake_caseVariables, funciones, módulosnombre_completo, calcular_precio()
UPPER_SNAKEConstantes (valores que no cambian)MAX_CONEXIONES = 10
PascalCaseNombres de clases (módulo 5)class CuentaBancaria:
_privadoConvención: «uso interno»_contador_interno

🚀 Siguiente paso: operadores

Ya sabes qué son las variables, cómo funcionan los 5 tipos fundamentales, qué es el tipado dinámico y cómo convertir entre tipos. Con esto puedes manejar cualquier dato básico en Python.

En la siguiente lección veremos los operadores en profundidad: aritméticos, de comparación, lógicos, de asignación compuesta y los operadores específicos de Python como is, in y las expresiones de asignación con :=. El operador módulo (%) que usaste en la lección anterior, la prioridad de operaciones y todas esas cosas que parecen triviales pero que cuando no las tienes claras generan bugs sutiles.

💡 Practica antes de continuar
Abre VS Code y escribe 10 variables de distintos tipos. Comprueba el tipo de cada una con type(). Prueba a hacer conversiones entre ellas y observa qué pasa cuando la conversión no es válida. No hay mejor forma de asimilar esto que ver los mensajes de error de primera mano.

❓ Preguntas frecuentes

❓ Preguntas frecuentes sobre Variables y tipos de datos en Python: la guía que ojalá hubiera tenido cuando empecé

Las dudas más comunes respondidas de forma clara y directa.

Tantas como quieras, limitado únicamente por la memoria disponible. Python no tiene un número máximo de variables. En la práctica, un script normal usa decenas; una aplicación grande, cientos o miles.
int almacena números enteros sin decimales (42, -7, 0) y tiene precisión exacta. float almacena números con decimales usando punto flotante IEEE 754, lo que implica pequeños errores de representación. Usa int siempre que puedas; pasa a float cuando necesites decimales.
Es un problema del estándar IEEE 754, no de Python. Los números decimales como 0.1 no tienen representación exacta en binario, igual que 1/3 no tiene representación exacta en decimal. Para cálculos financieros donde la precisión exacta importa, usa el módulo decimal de la librería estándar.
Técnicamente sí, Python 3 permite identificadores Unicode. Puedes escribir año = 2026 sin error. Sin embargo, por convención y compatibilidad, se recomienda usar solo caracteres ASCII (sin tildes, sin eñes) en nombres de variables. El código fuente lo editarán personas con distintas configuraciones de teclado.
Son valores completamente distintos aunque ambos sean "falsy". None representa la ausencia de valor — "no tengo nada aquí". False representa el valor lógico falso. La distinción importa mucho: una función que no devuelve nada devuelve None implícitamente. Una comparación que falla devuelve False. Comprueba con "is None" y no con "== False".
No, Python NO hace coerción implícita de tipos. Si intentas sumar un entero y una cadena de texto, obtienes un TypeError inmediatamente. Esto es intencional: Python prefiere ser explícito y fallar pronto a hacer suposiciones que pueden llevar a errores difíciles de detectar. La conversión siempre debe ser explícita con int(), str(), float(), etc.

🎯 ¿Quieres certificarte en Python?

Ciberaula ofrece cursos bonificados de Python con tutor personal, desde nivel básico hasta IA y Machine Learning. Formación subvencionada por FUNDAE para trabajadores en activo.

Ver cursos de Python bonificados →
Valora este artículo

💬 Foro de discusión

¿Tienes dudas sobre Variables y tipos de datos en Python: la guía que ojalá hubiera tenido cuando empecé? Comparte tu pregunta con la comunidad.

¿Tienes cuenta? o comenta como invitado ↓

Todavía no hay mensajes. ¡Sé el primero en participar!