Python para Desarrolladores JavaScript: Guía Definitiva 2026
Aprende Python si ya sabes JavaScript. Comparativa directa de sintaxis, async, módulos, tipado y ecosistema. Con ejemplos paralelos JS vs Python para aprender 2x más rápido.
Tabla de contenidos
Sabes JavaScript. Quieres aprender Python. Buenas noticias: ya tienes el 60% aprendido. La lógica de programación, async/await, los módulos, los arrays y objetos… todo eso lo vas a reutilizar. Solo cambia la sintaxis y el ecosistema.
Esta guía va directa al grano: JS a la izquierda, Python a la derecha. Aprende por comparación.
Por qué aprender Python si ya sabes JavaScript
En 2026, Python es el lenguaje de la IA. Todos los modelos, librerías y tutoriales de machine learning usan Python por defecto. Si quieres:
- Llamar a APIs de IA de forma avanzada (fine-tuning, embeddings, RAG)
- Trabajar con datos (pandas, numpy)
- Automatizar tareas con scripts potentes
- Construir agentes de IA (LangChain, LlamaIndex)
- Acceder al mercado laboral data/ML
…Python es imprescindible. Y si ya sabes JS, aprenderlo es más fácil que para la mayoría.
Sintaxis básica: comparativa directa
Variables y tipos
// JavaScript
const nombre = "Ana"
let edad = 28
const activo = true
const precio = 9.99
// Tipos con TypeScript
const nombre: string = "Ana"
const edad: number = 28
# Python
nombre = "Ana"
edad = 28
activo = True
precio = 9.99
# Tipos con type hints (opcional pero recomendado)
nombre: str = "Ana"
edad: int = 28
Diferencias clave:
- Sin
const,let,var. Solo asignación directa True/Falsecon mayúscula (notrue/false)- Sin punto y coma al final
- La indentación es obligatoria y define los bloques (sin llaves
{})
Strings
// JavaScript
const saludo = `Hola, ${nombre}! Tienes ${edad} años`
const upper = nombre.toUpperCase()
const partes = "hola mundo".split(" ")
const sinEspacios = " hola ".trim()
# Python
saludo = f"Hola, {nombre}! Tienes {edad} años" # f-string
upper = nombre.upper()
partes = "hola mundo".split(" ")
sin_espacios = " hola ".strip()
Los f-strings de Python son exactamente como los template literals de JS. La sintaxis de métodos es casi idéntica.
Condicionales
// JavaScript
if (edad >= 18) {
console.log("Mayor de edad")
} else if (edad >= 16) {
console.log("Casi")
} else {
console.log("Menor")
}
// Ternario
const estado = edad >= 18 ? "adulto" : "menor"
# Python
if edad >= 18:
print("Mayor de edad")
elif edad >= 16:
print("Casi")
else:
print("Menor")
# Ternario
estado = "adulto" if edad >= 18 else "menor"
else if→elif- Sin llaves, con
:al final y sangría - El ternario Python es al revés:
valor_si_true if condicion else valor_si_false
Bucles
// JavaScript
for (let i = 0; i < 5; i++) {
console.log(i)
}
// forEach
const nums = [1, 2, 3, 4, 5]
nums.forEach(n => console.log(n))
// for...of
for (const n of nums) {
console.log(n)
}
// while
let i = 0
while (i < 5) {
console.log(i)
i++
}
# Python
for i in range(5):
print(i)
# Iterar lista (equivale a for...of)
nums = [1, 2, 3, 4, 5]
for n in nums:
print(n)
# enumerate si necesitas el índice
for i, n in enumerate(nums):
print(f"{i}: {n}")
# while
i = 0
while i < 5:
print(i)
i += 1
Python no tiene for de 3 partes. Usa range(n) para contar, for x in lista para iterar.
Arrays → Listas. Objetos → Diccionarios
Arrays / Listas
// JavaScript
const frutas = ["manzana", "pera", "uva"]
frutas.push("naranja")
frutas.pop()
const primera = frutas[0]
const longitud = frutas.length
const sinPrimera = frutas.slice(1)
// map, filter, reduce
const mayus = frutas.map(f => f.toUpperCase())
const largas = frutas.filter(f => f.length > 4)
const total = [1, 2, 3].reduce((acc, n) => acc + n, 0)
# Python
frutas = ["manzana", "pera", "uva"]
frutas.append("naranja") # push → append
frutas.pop() # igual
primera = frutas[0]
longitud = len(frutas) # .length → len()
sin_primera = frutas[1:] # slicing nativo
# List comprehensions (más idiomático que map/filter)
mayus = [f.upper() for f in frutas]
largas = [f for f in frutas if len(f) > 4]
total = sum([1, 2, 3]) # reduce para sumas → sum()
# map y filter existen pero se usan menos
mayus2 = list(map(lambda f: f.upper(), frutas))
largas2 = list(filter(lambda f: len(f) > 4, frutas))
Las list comprehensions son la forma más pythonica de hacer map/filter. Apréndetelas:
# [expresion for variable in iterable if condicion]
cuadrados_pares = [x**2 for x in range(10) if x % 2 == 0]
# → [0, 4, 16, 36, 64]
Objetos / Diccionarios
// JavaScript
const usuario = {
nombre: "Ana",
edad: 28,
activo: true
}
// Acceso
console.log(usuario.nombre)
console.log(usuario["nombre"])
// Destructuring
const { nombre, edad } = usuario
// Spread
const nuevo = { ...usuario, rol: "admin" }
// Verificar si existe una key
if ("nombre" in usuario) { ... }
if (usuario.hasOwnProperty("nombre")) { ... }
# Python
usuario = {
"nombre": "Ana",
"edad": 28,
"activo": True
}
# Acceso
print(usuario["nombre"]) # siempre con corchetes
print(usuario.get("nombre")) # sin KeyError si no existe
# "Destructuring" — no existe igual, pero hay desempaquetado
nombre, edad = usuario["nombre"], usuario["edad"]
# Merge (Python 3.9+)
nuevo = {**usuario, "rol": "admin"}
# Verificar si existe una key
if "nombre" in usuario: ...
En Python las keys de los dicts van siempre con comillas. No hay notación de punto para acceder a valores (eso es para atributos de clases/objetos).
Funciones
// JavaScript
function sumar(a, b) {
return a + b
}
// Arrow function
const multiplicar = (a, b) => a * b
// Default params
function saludar(nombre = "Mundo") {
return `Hola, ${nombre}!`
}
// Rest params
function suma(...nums) {
return nums.reduce((a, b) => a + b, 0)
}
// Objeto como parámetro (named params)
function crear({ nombre, edad = 25 }) {
return { nombre, edad }
}
# Python
def sumar(a, b):
return a + b
# Lambda (como arrow function simple)
multiplicar = lambda a, b: a * b
# Default params
def saludar(nombre="Mundo"):
return f"Hola, {nombre}!"
# Args variables (*args equivale a rest)
def suma(*nums):
return sum(nums)
# Keyword arguments (named params)
def crear(nombre, edad=25):
return {"nombre": nombre, "edad": edad}
crear(nombre="Ana", edad=30) # llamada con kwargs
Clases
// JavaScript
class Persona {
constructor(nombre, edad) {
this.nombre = nombre
this.edad = edad
}
saludar() {
return `Hola, soy ${this.nombre}`
}
static crear(nombre, edad) {
return new Persona(nombre, edad)
}
}
class Empleado extends Persona {
constructor(nombre, edad, empresa) {
super(nombre, edad)
this.empresa = empresa
}
}
# Python
class Persona:
def __init__(self, nombre: str, edad: int):
self.nombre = nombre
self.edad = edad
def saludar(self) -> str:
return f"Hola, soy {self.nombre}"
@staticmethod
def crear(nombre: str, edad: int) -> "Persona":
return Persona(nombre, edad)
class Empleado(Persona):
def __init__(self, nombre: str, edad: int, empresa: str):
super().__init__(nombre, edad)
self.empresa = empresa
constructor→__init__this.→self.(yselfva siempre como primer parámetro)extends→ el nombre de la clase entre paréntesisstatic→ decorador@staticmethod
Async/Await
En JavaScript, async/await es para Promises. En Python es para corrutinas. La sintaxis es casi idéntica:
// JavaScript
async function obtenerUsuario(id) {
try {
const response = await fetch(`/api/users/${id}`)
const data = await response.json()
return data
} catch (error) {
console.error("Error:", error)
throw error
}
}
// Promise.all
const [user, posts] = await Promise.all([
obtenerUsuario(1),
obtenerPosts(1)
])
# Python (con httpx o aiohttp en vez de fetch)
import httpx
async def obtener_usuario(id: int):
try:
async with httpx.AsyncClient() as client:
response = await client.get(f"/api/users/{id}")
data = response.json()
return data
except Exception as error:
print(f"Error: {error}")
raise
# asyncio.gather equivale a Promise.all
import asyncio
user, posts = await asyncio.gather(
obtener_usuario(1),
obtener_posts(1)
)
Para ejecutar código async en Python necesitas asyncio.run() o un framework async (FastAPI, Starlette):
import asyncio
async def main():
resultado = await obtener_usuario(1)
print(resultado)
asyncio.run(main())
Módulos
// JavaScript (ES Modules)
// math.js
export const PI = 3.14159
export function sumar(a, b) { return a + b }
export default function multiplicar(a, b) { return a * b }
// main.js
import multiplicar, { PI, sumar } from './math.js'
import * as math from './math.js'
# Python
# math_utils.py
PI = 3.14159
def sumar(a, b): return a + b
def multiplicar(a, b): return a * b
# main.py
from math_utils import PI, sumar, multiplicar
import math_utils # como import * as
from math_utils import multiplicar as mult # alias
En Python no hay export. Todo lo definido en un módulo es importable por defecto.
Gestión de paquetes: npm → pip + venv
# JavaScript
npm init
npm install express
npm install -D eslint
cat package.json
# Python equivalente
python -m venv venv # crear entorno virtual (como node_modules aislado)
venv\Scripts\activate # Windows
source venv/bin/activate # Mac/Linux
pip install fastapi
pip install --dev ruff # no hay -D exacto, usar grupos en pyproject.toml
cat requirements.txt # o pyproject.toml
Importante: Siempre usa venv (entorno virtual). Es el equivalente a node_modules pero tienes que activarlo manualmente. Sin él, instalas paquetes globalmente (malo).
# Guardar dependencias (como package.json)
pip freeze > requirements.txt
# Instalar desde requirements.txt (como npm install)
pip install -r requirements.txt
Para proyectos modernos, usa uv en vez de pip — es el equivalente a npm para Python, mucho más rápido:
pip install uv
uv init mi-proyecto
uv add fastapi httpx
uv run python main.py
El ecosistema Python para devs JS
| Necesidad | JavaScript | Python |
|---|---|---|
| API REST | Express, Fastify, Hono | FastAPI, Flask, Django |
| ORM | Prisma, Drizzle | SQLAlchemy, Tortoise, Peewee |
| Validación | Zod | Pydantic |
| Testing | Jest, Vitest | pytest |
| Linting | ESLint | Ruff |
| Formatter | Prettier | Black, Ruff |
| Build tool | Vite, esbuild | uv, Poetry |
| IA/ML | — | PyTorch, LangChain, HuggingFace |
| Data | — | pandas, numpy, polars |
Tu primer API con FastAPI (el Express de Python)
# main.py
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
# Modelo (como un schema de Zod)
class Usuario(BaseModel):
nombre: str
edad: int
usuarios = []
@app.get("/usuarios")
async def listar():
return usuarios
@app.post("/usuarios")
async def crear(usuario: Usuario):
usuarios.append(usuario)
return {"mensaje": "creado", "usuario": usuario}
@app.get("/usuarios/{id}")
async def obtener(id: int):
if id >= len(usuarios):
return {"error": "no encontrado"}, 404
return usuarios[id]
pip install fastapi uvicorn
uvicorn main:app --reload
# API corriendo en http://localhost:8000
# Docs automáticas en http://localhost:8000/docs ← ¡Esto no tiene Express!
FastAPI genera Swagger UI automáticamente. Sin instalar nada extra.
Resumen rápido de diferencias
| Concepto | JavaScript | Python |
|---|---|---|
| Bloques | { } | Indentación |
| Booleanos | true/false | True/False |
| Nulo | null/undefined | None |
| Array | Array | list |
| Objeto | Object | dict |
| String length | .length | len() |
| Console | console.log() | print() |
| Módulos | import/export | import (sin export) |
| Clases | constructor, this | __init__, self |
| Herencia | extends | class Hijo(Padre) |
| try/catch | catch (e) | except Exception as e |
| Ternario | cond ? a : b | a if cond else b |
Con esto tienes todo lo que necesitas para empezar. Pon en práctica con un script pequeño o construye una API con FastAPI — en 3 días ya no estarás consultando esta guía.