Saltar al contenido principal

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.

Fran Cobos 10 min de lectura 1913 palabras

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/False con mayúscula (no true/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 ifelif
  • 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. (y self va siempre como primer parámetro)
  • extends → el nombre de la clase entre paréntesis
  • static → 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

NecesidadJavaScriptPython
API RESTExpress, Fastify, HonoFastAPI, Flask, Django
ORMPrisma, DrizzleSQLAlchemy, Tortoise, Peewee
ValidaciónZodPydantic
TestingJest, Vitestpytest
LintingESLintRuff
FormatterPrettierBlack, Ruff
Build toolVite, esbuilduv, Poetry
IA/MLPyTorch, LangChain, HuggingFace
Datapandas, 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

ConceptoJavaScriptPython
Bloques{ }Indentación
Booleanostrue/falseTrue/False
Nulonull/undefinedNone
ArrayArraylist
ObjetoObjectdict
String length.lengthlen()
Consoleconsole.log()print()
Módulosimport/exportimport (sin export)
Clasesconstructor, this__init__, self
Herenciaextendsclass Hijo(Padre)
try/catchcatch (e)except Exception as e
Ternariocond ? a : ba 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.

Fran Cobos

Fran Cobos

Desarrollador Full Stack especializado en IA aplicada, automatización y desarrollo web. Escribo sobre herramientas, tutoriales y casos reales para programadores.

¿Necesitas desarrollo a medida?

Apps web, IA, módulos ERP — cuéntame tu proyecto.