python-interview-questions

Read in other languages: English 馃嚭馃嚫, Polska 馃嚨馃嚤, German 馃嚛馃嚜, French 馃嚝馃嚪, Spanish 馃嚜馃嚫, 校泻褉邪褩薪褋褜泻邪 馃嚭馃嚘.

Python Python logo

Las preguntas y respuestas m谩s populares de entrevistas sobre Python

1. 驴Qu茅 es Python y cu谩les son sus caracter铆sticas principales? #### Python **Python** es un lenguaje de alto nivel y de prop贸sito general, enfocado en la legibilidad, el desarrollo r谩pido y una amplia biblioteca est谩ndar. Caracter铆sticas principales: - **Sintaxis simple**: el c贸digo es f谩cil de leer y mantener. - **Modelo de ejecuci贸n interpretado**: ciclo r谩pido de cambios sin una fase de compilaci贸n manual. - **Multiplataforma**: el mismo c贸digo funciona en Linux, macOS y Windows. - **Multiparadigma**: enfoques procedimental, POO y funcional en un mismo proyecto. - **Ecosistema s贸lido**: `pip`, `venv`, `pyproject.toml` y miles de bibliotecas listas para usar. - **Funciones modernas de Python 3.10+**: anotaciones de tipos, `dataclass`, `async/await`, `match/case`, generadores y gestores de contexto. Ejemplo de una funci贸n con estilo de producci贸n: ```python from dataclasses import dataclass @dataclass(slots=True) class User: name: str active: bool def process_users(users: list[User]) -> list[str]: return [user.name for user in users if user.active] ``` **En resumen:** - Python acelera el desarrollo gracias a su sintaxis simple y a su gran biblioteca est谩ndar. - El lenguaje sirve para back-end, automatizaci贸n, datos/ML, pruebas y DevOps. - En Python 3.10+, las pr谩cticas clave son las anotaciones de tipos, el I/O as铆ncrono y una biblioteca est谩ndar moderna.
2. 驴Cu谩les son las ventajas clave de Python? #### Python Ventajas clave de Python en producci贸n: - alta velocidad de desarrollo gracias a su sintaxis concisa; - gran biblioteca est谩ndar (`pathlib`, `itertools`, `collections`, `asyncio`); - ecosistema maduro de paquetes para back-end, datos, automatizaci贸n y pruebas; - portabilidad del c贸digo entre distintos sistemas operativos; - buen soporte para tipado (`typing`, `mypy`, `pyright`) y pr谩cticas modernas. **En resumen:** - Python reduce el tiempo de salida al mercado. - Proporciona muchas herramientas listas para usar sin dependencias adicionales. - Sirve tanto para MVP como para servicios escalables.
3. 驴En qu茅 se diferencia Python de los lenguajes compilados? #### Python Python normalmente se ejecuta mediante un int茅rprete: el c贸digo se compila a bytecode y se ejecuta en tiempo de ejecuci贸n en la VM de CPython. En los lenguajes compilados como C/C++ o Rust, normalmente hay una compilaci贸n previa a c贸digo m谩quina. Consecuencias pr谩cticas: - Python es m谩s r谩pido para desarrollo y prototipado. - Los lenguajes compilados nativos suelen ser m谩s r谩pidos en tareas intensivas de CPU. - En Python, el rendimiento suele mejorarse con algoritmos, perfilado y extensiones en C. **En resumen:** - Python optimiza la velocidad de desarrollo. - La compilaci贸n a c贸digo m谩quina normalmente ofrece mejor rendimiento bruto. - La elecci贸n depende del dominio y de los requisitos de latencia y rendimiento.
4. 驴Qu茅 significa el tipado din谩mico en Python? #### Python El tipado din谩mico significa que el tipo est谩 asociado al objeto, no al nombre de la variable. Un nombre puede referirse a valores de distintos tipos en diferentes momentos de la ejecuci贸n. ```python value = 10 # int value = "10" # str ``` Los tipos se comprueban durante la ejecuci贸n, por lo que los errores de tipos aparecen en tiempo de ejecuci贸n si no se usa un analizador est谩tico de tipos. **En resumen:** - En Python, el tipo pertenece al objeto, no a la variable. - El tipo puede cambiar cuando se reasigna el nombre. - Las anotaciones de tipos a帽aden control antes de ejecutar el c贸digo.
5. 驴Qu茅 significa strong typing en Python? #### Python Strong typing en Python significa que el int茅rprete no realiza conversiones impl铆citas peligrosas entre tipos incompatibles. ```python 1 + "2" # TypeError ``` Para operar entre tipos distintos se requiere una conversi贸n expl铆cita: ```python 1 + int("2") # 3 ``` **En resumen:** - Python tiene tipado din谩mico, pero es estricto respecto a la compatibilidad de tipos. - Las conversiones impl铆citas peligrosas se bloquean con un error. - La conversi贸n expl铆cita hace que el comportamiento sea predecible.
6. 驴Qu茅 es el REPL y cu谩ndo se utiliza? #### Python El REPL (Read-Eval-Print Loop) es un modo interactivo en el que introduces una expresi贸n, obtienes el resultado de inmediato y validas hip贸tesis r谩pidamente. Casos de uso: - comprobar la API de una biblioteca; - probar r谩pidamente una expresi贸n o un algoritmo; - explorar datos antes de implementarlos en un m贸dulo. Herramientas: `python` est谩ndar, `ipython`, `ptpython`. **En resumen:** - El REPL ofrece el ciclo de retroalimentaci贸n m谩s r谩pido. - Es 煤til para experimentos y para depurar. - No sustituye a las pruebas, pero reduce el tiempo para validar ideas.
7. 驴Qu茅 son los literals en Python? Da ejemplos de distintos tipos. #### Python Un literal es un valor fijo escrito directamente en el c贸digo. ```python name = "Ada" # str literal count = 42 # int literal ratio = 3.14 # float literal enabled = True # bool literal items = [1, 2, 3] # list literal config = {"retries": 3} # dict literal flags = {"a", "b"} # set literal point = (10, 20) # tuple literal raw = b"abc" # bytes literal ``` **En resumen:** - Los literals son valores constantes incorporados en el c贸digo. - Cada tipo b谩sico tiene su propia sintaxis literal. - Se usan con frecuencia para inicializar datos.
8. 驴Qu茅 son las keywords en Python? #### Python Las keywords son palabras reservadas del lenguaje con un prop贸sito sint谩ctico especial y no pueden usarse como nombres de variables. Ejemplos: `if`, `for`, `class`, `def`, `match`, `case`, `try`, `except`, `async`, `await`. Para ver la lista: ```python import keyword print(keyword.kwlist) ``` **En resumen:** - Las keywords definen la sintaxis de Python. - No pueden usarse como identificadores. - La lista est谩 disponible a trav茅s del m贸dulo `keyword`.
9. 驴Qu茅 es una variable en Python? #### Python Una variable en Python es un nombre, una referencia, que apunta a un objeto en memoria. La asignaci贸n vincula el nombre con el objeto, no "mete el valor en una caja". ```python x = [1, 2] y = x y.append(3) # x e y apuntan a la misma lista ``` **En resumen:** - Una variable es una referencia a un objeto. - Varios nombres pueden apuntar al mismo objeto mutable. - Esto es importante para entender las copias y los efectos secundarios.
10. 驴Qu茅 son `pass` y `...` (Ellipsis) en Python? #### Python `pass` es una instrucci贸n vac铆a: no hace nada, pero permite definir un bloque vac铆o sint谩cticamente correcto. `...` (Ellipsis) es un objeto separado, `Ellipsis`. A menudo se usa como marca de "a煤n no implementado", en anotaciones de tipos y en bibliotecas como NumPy. ```python def feature() -> None: pass PLACEHOLDER = ... ``` **En resumen:** - `pass` se necesita para bloques de c贸digo vac铆os. - `...` es un valor-objeto, no una keyword. - Ambos se usan como marcadores temporales, pero con distinta sem谩ntica.
11. 驴Qu茅 es PEP y c贸mo influye en la evoluci贸n de Python? #### Python PEP (Python Enhancement Proposal) es un documento oficial que describe una nueva funcionalidad, un est谩ndar o un proceso dentro del ecosistema de Python. A trav茅s de un PEP pasan: - discusi贸n de dise帽o; - argumentaci贸n t茅cnica; - decisi贸n de aceptaci贸n o rechazo; - estandarizaci贸n de pr谩cticas. Ejemplos: PEP 8 (estilo), PEP 484 (anotaciones de tipos), PEP 634 (coincidencia estructural de patrones). **En resumen:** - PEP es el mecanismo de evoluci贸n del lenguaje y de sus herramientas. - Hace que los cambios sean transparentes y formalizados. - Muchas pr谩cticas modernas de Python quedaron fijadas precisamente a trav茅s de los PEP.
12. 驴Qu茅 es PEP 8 y para qu茅 sirve? #### Python PEP 8 es la gu铆a oficial de estilo para c贸digo Python: nombres, formato, indentaci贸n, importaciones, longitud de l铆neas y legibilidad de construcciones. Para qu茅 sirve: - el c贸digo mantiene un estilo uniforme en el equipo; - el code review es m谩s r谩pido; - hay menos ruido en el diff; - aumenta la mantenibilidad. En la pr谩ctica, el estilo se automatiza con `ruff format` o con `black` + `ruff`. **En resumen:** - PEP 8 estandariza el estilo del c贸digo Python. - Trata de legibilidad y mantenimiento, no de rendimiento. - Su cumplimiento se automatiza mejor con herramientas.
13. 驴Qu茅 funcionalidades nuevas aparecieron en las versiones modernas de Python 3.10+? #### Python Funcionalidades clave de Python moderno: - `match/case` (coincidencia estructural de patrones); - mejoras en la sintaxis y en los mensajes de error; - union types con `|` (`int | None`); - `typing.Self`, `typing.TypeAlias`, `typing.override`; - generics al estilo de PEP 695 (`class Box[T]: ...`, `def f[T](...) -> ...`); - `tomllib` en la biblioteca est谩ndar. En la pr谩ctica, esto reduce el c贸digo repetitivo y mejora la fiabilidad del c贸digo tipado. **En resumen:** - Python 3.10+ mejor贸 de forma notable la sintaxis y el typing. - `match/case` y el `typing` moderno son lo que m谩s impacta el c贸digo. - Las nuevas features conviene usarlas por defecto en c贸digo nuevo.
14. 驴Qu茅 es un docstring en Python? #### Python Un docstring es una cadena de documentaci贸n, la primera expresi贸n dentro de un m贸dulo, clase o funci贸n. Est谩 disponible mediante `__doc__` y la usan IDEs, `help()` y generadores de documentaci贸n. ```python def normalize_email(email: str) -> str: """Return lowercase email without surrounding spaces.""" return email.strip().lower() ``` Se recomienda describir qu茅 hace la funci贸n, sus argumentos, el valor de retorno y las excepciones. **En resumen:** - El docstring es documentaci贸n integrada en el c贸digo. - Sirve como fuente para `help()` y para la generaci贸n autom谩tica de docs. - Un buen docstring reduce la necesidad de leer la implementaci贸n.
15. 驴C贸mo funcionan las indentaciones en Python? #### Python En Python, la indentaci贸n define los bloques de c贸digo, como el cuerpo de `if`, `for`, `def` o `class`. Es decir, la indentaci贸n es parte de la sintaxis, no solo del estilo. ```python if is_ready: run_task() else: stop_task() ``` Mezclar tabs y spaces puede provocar `IndentationError` o una estructura de bloque incorrecta. **En resumen:** - La indentaci贸n en Python define la estructura del programa. - Una indentaci贸n incorrecta rompe la ejecuci贸n. - Usa un estilo consistente: 4 espacios.
16. 驴Cu谩ntos espacios deben usarse para la indentaci贸n seg煤n PEP 8 y por qu茅 es importante mantenerla consistente? #### Python PEP 8 recomienda **4 espacios** por cada nivel de indentaci贸n. Por qu茅 es importante: - estructura de bloques uniforme en todo el proyecto; - apariencia predecible en distintos editores; - menos errores por conflictos entre tab y space; - diffs m谩s limpios en Git. **En resumen:** - La indentaci贸n est谩ndar es de 4 espacios. - Un estilo 煤nico elimina toda una clase de errores de formato. - Esto mejora directamente la legibilidad y el mantenimiento del c贸digo.
17. 驴Cu谩l es la diferencia entre `ruff` y `black` en funcionalidad y uso? #### Python `black` es un formateador de c贸digo con reglas fijas. `ruff` es un linter r谩pido, adem谩s de formateador y autofixer de muchas reglas como PEP 8, imports, bugs potenciales y simplificaciones de sintaxis. En la pr谩ctica: - o bien `ruff check --fix` + `ruff format`; - o bien `ruff` para an谩lisis est谩tico + `black` para formateo. **En resumen:** - `black` se centra en el formateo. - `ruff` cubre el linting y parte de las autocorrecciones. - En proyectos modernos, a menudo basta con solo `ruff`.
18. Explica el prop贸sito de las anotaciones de tipos en Python y muestra un ejemplo de funci贸n con anotaciones de tipos. #### Python Las anotaciones de tipos describen los tipos esperados de los argumentos y del valor de retorno. Mejoran el autocompletado, el an谩lisis est谩tico y la legibilidad de la API. ```python def process_users(users: list[dict[str, object]]) -> list[str]: return [str(user["name"]) for user in users if bool(user.get("active"))] ``` Las anotaciones no realizan validaci贸n en tiempo de ejecuci贸n por s铆 mismas, pero ayudan a detectar errores en CI mediante `mypy` o `pyright`. **En resumen:** - Las anotaciones de tipos documentan el contrato de la funci贸n. - Permiten detectar errores antes mediante comprobaci贸n est谩tica. - Mejoran la calidad de la API en bases de c贸digo grandes.
19. 驴Qu茅 es la depuraci贸n y por qu茅 es una habilidad importante para los programadores? #### Python La depuraci贸n es la b煤squeda sistem谩tica de la causa de un comportamiento incorrecto del c贸digo y su correcci贸n. No es solo "encontrar un bug", sino reproducirlo, localizarlo y verificar la correcci贸n. Ciclo b谩sico: - reproducir el problema; - reducir la zona de c贸digo; - comprobar la hip贸tesis con logs o depurador; - a帽adir un test que fije el escenario. **En resumen:** - La depuraci贸n reduce el MTTR y la cantidad de regresiones. - Funciona mejor como proceso, no como b煤squeda ca贸tica. - El cierre correcto de la depuraci贸n es: correcci贸n + test + verificaci贸n posterior.
20. Explica el prop贸sito de usar `print` para depurar. Da un ejemplo de una situaci贸n donde este enfoque sea 煤til. #### Python La depuraci贸n con `print` es una forma r谩pida de comprobar valores de variables y el orden de ejecuci贸n sin lanzar herramientas m谩s complejas. Es 煤til cuando necesitas validar r谩pidamente una hip贸tesis en un script local: ```python def parse_port(raw: str) -> int: value = raw.strip() print(f"raw={raw!r} value={value!r}") return int(value) ``` Para c贸digo de producci贸n, es mejor pasar a `logging`, para disponer de niveles de log y una salida controlada. **En resumen:** - `print` sirve para un diagn贸stico local corto. - Muestra r谩pidamente el estado de las variables en el punto problem谩tico. - Para un diagn贸stico estable en un servicio, usa `logging`.
21. Describe c贸mo usar Python Debugger (PDB) para depurar. 驴Qu茅 ventajas tiene PDB frente a `print`? #### Python `pdb` permite detener la ejecuci贸n del programa, avanzar l铆nea por l铆nea, ver el estado de las variables y la pila de llamadas. Uso b谩sico: ```python import pdb def compute(x: int) -> int: pdb.set_trace() return x * 2 ``` Comandos clave: `n` (next), `s` (step), `c` (continue), `p expr` (print expr), `l` (list), `bt` (backtrace). **En resumen:** - `pdb` da control interactivo sobre la ejecuci贸n. - Es m谩s eficaz que `print` para escenarios complejos. - Permite diagnosticar el estado sin ensuciar el c贸digo con logs.
22. 驴Qu茅 estrategias se pueden aplicar para depurar bucles y funciones en Python? #### Python Estrategias pr谩cticas: - aislar el error con un ejemplo m铆nimo reproducible; - registrar invariantes en las iteraciones del bucle; - poner breakpoints en la entrada y salida de la funci贸n; - comprobar casos l铆mite como datos vac铆os, `None` o vol煤menes grandes; - cubrir la ruta problem谩tica con un test. En los bucles, es 煤til registrar el 铆ndice y los estados intermedios clave. **En resumen:** - Empieza reproduciendo y acotando el problema. - Comprueba invariantes y condiciones l铆mite. - Cierra el fix con un test que detecte la regresi贸n.
23. 驴Qu茅 impacto tienen las funciones de larga duraci贸n en el rendimiento del programa? #### Python Las funciones de larga duraci贸n aumentan la latencia y bloquean procesos de trabajo o hilos y empeoran el rendimiento del servicio. Riesgos: - respuestas lentas de la API; - tiempos de espera; - crecimiento de las colas de tareas; - peor uso de CPU e I/O. Enfoque: perfilar con `cProfile`, dividir en pasos m谩s peque帽os, usar generadores o procesamiento en flujo y mover los c谩lculos pesados a `multiprocessing` o a tareas en segundo plano. **En resumen:** - Las funciones largas golpean directamente la latencia. - La optimizaci贸n debe basarse en perfilado, no en intuici贸n. - A nivel de arquitectura, conviene separar el trabajo intensivo de CPU del intensivo de I/O.
24. 驴Qu茅 es logging y por qu茅 es mejor usarlo en lugar de `print`? #### Python `logging` es el mecanismo est谩ndar para registrar eventos con niveles como `DEBUG`, `INFO`, `WARNING`, `ERROR` y `CRITICAL`, adem谩s de formatos y handlers como consola y archivo. Por qu茅 es mejor que `print`: - niveles de detalle controlables; - formato estructurado; - configuraci贸n centralizada; - posibilidad de integraci贸n con un stack de observability. **En resumen:** - `logging` sirve para producci贸n; `print`, no. - Los niveles de log permiten controlar el ruido. - Los logs deben ser estructurados y consistentes.
25. 驴Qu茅 es un traceback? #### Python Un traceback es el stack de llamadas que Python muestra cuando ocurre una excepci贸n: d贸nde empez贸 la ejecuci贸n, por qu茅 funciones pas贸 el c贸digo y en qu茅 punto exacto ocurri贸 el error. Uso: - encontrar r谩pidamente el archivo y la l铆nea del origen del error; - entender el camino de ejecuci贸n hasta el fallo; - construir un test preciso para reproducirlo. **En resumen:** - El traceback es la "ruta" hacia el error. - La parte m谩s valiosa son los 煤ltimos frames del stack y el tipo de excepci贸n. - Analizar el traceback acelera el root cause analysis.
26. 驴Cu谩les son los tipos de datos principales en Python? #### Python Tipos built-in principales: - num茅ricos: `int`, `float`, `complex`; - l贸gico: `bool`; - cadenas y bytes: `str`, `bytes`, `bytearray`; - colecciones: `list`, `tuple`, `set`, `dict`, `frozenset`; - especiales: `NoneType` (`None`). Es importante entender la mutability: - mutable: `list`, `dict`, `set`, `bytearray`; - immutable: `int`, `str`, `tuple`, `frozenset`. **En resumen:** - Python incluye un conjunto rico de tipos b谩sicos "out of the box". - La elecci贸n de la estructura de datos afecta la complejidad de las operaciones. - La mutability define el comportamiento de las copias y de los efectos secundarios.
27. 驴Cu谩l es la diferencia entre la divisi贸n normal (`/`) y la divisi贸n entera (`//`) en Python? #### Python `/` realiza una divisi贸n normal y siempre devuelve `float`. `//` realiza una floor division: devuelve la parte entera hacia abajo, hasta `-鈭瀈, y normalmente el tipo es `int` cuando los operandos son enteros. ```python 7 / 2 # 3.5 7 // 2 # 3 -7 // 2 # -4 ``` **En resumen:** - `/` devuelve un resultado decimal. - `//` redondea hacia abajo hasta un entero. - Para n煤meros negativos, `//` no equivale a "truncar hacia cero".
28. Explica el uso del operador m贸dulo (`%`) en Python. 驴C贸mo se usa para saber si un n煤mero es par o impar? #### Python El operador `%` devuelve el resto de una divisi贸n. Comprobaci贸n de paridad: ```python def is_even(n: int) -> bool: return n % 2 == 0 ``` Si `n % 2 == 0`, el n煤mero es par; en caso contrario, es impar. Casos t铆picos: 铆ndices c铆clicos, partici贸n en grupos y c谩lculos de calendario. **En resumen:** - `%` devuelve el resto. - `n % 2` es la comprobaci贸n est谩ndar de paridad. - Se usa a menudo en l贸gica c铆clica.
29. 驴C贸mo trabaja Python con enteros grandes y qu茅 l铆mites existen al trabajar con n煤meros muy grandes? #### Python `int` en Python tiene precisi贸n arbitraria, es decir, no est谩 limitado a 32/64 bits como en muchos otros lenguajes. Los l铆mites son pr谩cticos: - memoria del proceso; - tiempo de c谩lculo con valores muy grandes; - el coste de las operaciones crece con el n煤mero de d铆gitos. **En resumen:** - No existe overflow de `int` en el sentido tradicional. - El l铆mite lo ponen los recursos de la m谩quina, no un tama帽o fijo en bits. - Para c谩lculos grandes, importan mucho los algoritmos y el perfilado.
30. 驴Qu茅 importancia tiene manejar la divisi贸n entre cero en Python y c贸mo prevenir `ZeroDivisionError` en el c贸digo? #### Python Dividir entre cero provoca `ZeroDivisionError`. Debe manejarse de forma expl铆cita si el divisor llega desde entrada externa o se calcula din谩micamente. ```python def safe_div(a: float, b: float) -> float | None: if b == 0: return None return a / b ``` En escenarios cr铆ticos, usa `try/except` y registra el contexto. **En resumen:** - Dividir entre cero es un error de ejecuci贸n controlado. - La prevenci贸n m谩s simple es comprobar el divisor antes de operar. - Con datos externos, a帽ade protecci贸n y diagn贸stico.
31. Describe el uso del m贸dulo `random` en Python. 驴Cu谩les son las funciones m谩s comunes de este m贸dulo? #### Python `random` se usa para valores pseudoaleatorios en simulaciones, datos de prueba y tareas no criptogr谩ficas. Funciones comunes: - `random()` devuelve un n煤mero en `[0.0, 1.0)`; - `randint(a, b)` devuelve un entero en un rango; - `randrange(start, stop, step)` funciona como `range`, pero devuelve un elemento aleatorio; - `choice(seq)` / `choices(seq, k=...)`; - `shuffle(list_)` mezcla una lista in-place; - `sample(population, k)` devuelve una muestra 煤nica. Para criptograf铆a, usa `secrets`, no `random`. **En resumen:** - `random` sirve para aleatoriedad de prop贸sito general. - Las m谩s usadas son `randint`, `choice`, `shuffle` y `sample`. - Para tareas sensibles a la seguridad, necesitas `secrets`.
32. 驴C贸mo trabajar con n煤meros con mejor precisi贸n en Python? #### Python Para c谩lculos financieros y decimales exactos, usa `decimal.Decimal` en lugar de `float`. ```python from decimal import Decimal total = Decimal("0.1") + Decimal("0.2") # Decimal('0.3') ``` Para n煤meros racionales, tambi茅n es 煤til `fractions.Fraction`. **En resumen:** - `float` es c贸modo, pero tiene errores por representaci贸n binaria. - Para aritm茅tica decimal exacta, elige `Decimal`. - El tipo num茅rico debe corresponder al dominio del problema.
33. 驴Qu茅 son los caracteres de escape en strings de Python y c贸mo se usan? Da ejemplos de `\n`, `\t`, `\r`, `\"` y `\'`. #### Python Las secuencias de escape son combinaciones especiales con `\` que codifican caracteres de control dentro de un string. - `\n` es nueva l铆nea - `\t` es tabulaci贸n - `\r` es retorno de carro - `\"` es una comilla doble dentro de un string con `"` - `\'` es una comilla simple dentro de un string con `'` ```python text = "A\tB\n\"quoted\"\nI\'m here\rX" ``` **En resumen:** - Los caracteres de escape controlan el formato del string. - Permiten insertar comillas sin romper la sintaxis. - Para rutas o regex, suele ser 煤til usar raw strings `r"..."`.
34. Explica el uso de los m茅todos `strip`, `lstrip` y `rstrip` en Python. 驴En qu茅 se diferencian? #### Python Estos m茅todos trabajan sobre los extremos del string: - `strip()` elimina caracteres de ambos lados; - `lstrip()` solo del lado izquierdo; - `rstrip()` solo del lado derecho. Por defecto, eliminan whitespace o un conjunto espec铆fico de caracteres: ```python " hello ".strip() # "hello" "--id--".strip("-") # "id" ``` **En resumen:** - La familia `strip` no modifica el string in-place, sino que devuelve uno nuevo. - La diferencia est谩 solo en el lado que se limpia. - Se usa muy a menudo sobre datos de entrada.
35. Describe el prop贸sito del m茅todo `count` en strings. 驴C贸mo funciona? #### Python `str.count(sub[, start[, end]])` cuenta cu谩ntas apariciones no superpuestas de la subcadena `sub` hay en el rango indicado. ```python "banana".count("an") # 2 "banana".count("a", 2) # 2 ``` Devuelve `0` si no hay coincidencias. **En resumen:** - `count` devuelve r谩pidamente la cantidad de apariciones de una subcadena. - Soporta limitar la b煤squeda con `start/end`. - Cuenta solo apariciones no superpuestas.
36. 驴C贸mo funciona el m茅todo `join` en Python y para qu茅 se usa con m谩s frecuencia? #### Python `sep.join(iterable)` une una secuencia de strings en un solo string usando `sep` como separador. ```python names = ["Ada", "Linus", "Guido"] result = ", ".join(names) # "Ada, Linus, Guido" ``` Usos t铆picos: construir strings tipo CSV, logs, fragmentos SQL, rutas URL y mensajes. **En resumen:** - `join` es la forma est谩ndar y r谩pida de concatenar strings. - Se llama sobre el separador, no sobre la lista. - Es m谩s eficiente que hacer `+=` muchas veces en un bucle.
37. 驴Qu茅 es slicing en Python y c贸mo se usa para obtener substrings? Da ejemplos con 铆ndices positivos y negativos. #### Python Slicing es la selecci贸n de una parte de una secuencia mediante `[start:stop:step]`. ```python s = "python" s[1:4] # "yth" s[:2] # "py" s[-3:] # "hon" s[::-1] # "nohtyp" ``` `start` se incluye y `stop` no se incluye. **En resumen:** - Slicing funciona con strings, listas y tuplas. - Los 铆ndices negativos se cuentan desde el final. - Es una herramienta b谩sica para procesar secuencias sin bucles.
38. Explica el m茅todo `replace` para strings. 驴C贸mo puede usarse para reemplazar varias apariciones de una subcadena? #### Python `str.replace(old, new, count=-1)` devuelve un nuevo string donde `old` se reemplaza por `new`. Por defecto, reemplaza todas las apariciones. ```python "foo bar foo".replace("foo", "baz") # "baz bar baz" "foo bar foo".replace("foo", "baz", 1) # "baz bar foo" ``` **En resumen:** - `replace` no modifica el string in-place. - Sin `count`, reemplaza todas las apariciones. - `count` permite controlar cu谩ntos reemplazos se hacen.
39. 驴C贸mo funciona el m茅todo `split` en strings? #### Python `split(sep=None, maxsplit=-1)` divide un string en una lista de subcadenas. - sin `sep`, divide por cualquier whitespace; - con `sep`, divide por un separador concreto; - `maxsplit` limita el n煤mero de divisiones. ```python "a,b,c".split(",") # ["a", "b", "c"] "a b c".split() # ["a", "b", "c"] "k=v=x".split("=", 1) # ["k", "v=x"] ``` **En resumen:** - `split` convierte un string en una lista de tokens. - `sep=None` tiene un comportamiento especial para whitespace. - `maxsplit` es 煤til para parsear formatos key/value.
40. 驴C贸mo funciona la conversi贸n de tipos (type casting)? #### Python Type casting es la conversi贸n expl铆cita de un valor entre tipos mediante constructores como `int()`, `float()`, `str()`, `bool()`, `list()`, `tuple()`, `set()` y `dict()`. ```python age = int("42") price = float("19.99") text = str(10) ``` Los datos incorrectos provocan una excepci贸n como `ValueError` o `TypeError`, por lo que la entrada externa requiere validaci贸n. **En resumen:** - Python ofrece funciones expl铆citas de conversi贸n de tipos. - No todos los valores pueden convertirse de forma segura. - La entrada del usuario requiere validaci贸n y manejo de excepciones.
41. 驴C贸mo convierte Python autom谩ticamente distintos tipos de datos a valores booleanos? #### Python En un contexto booleano, Python aplica las reglas de truthiness. Valores falsy: - `False`, `None`; - n煤meros cero: `0`, `0.0`, `0j`; - colecciones vac铆as: `""`, `[]`, `{}`, `set()`, `tuple()`, `range(0)`. Todo lo dem谩s suele ser `True`. ```python bool([]) # False bool("0") # True ``` **En resumen:** - La conversi贸n a booleano se basa en reglas truthy/falsy. - Lo vac铆o y lo cero dan `False`. - El string no vac铆o `"0"` sigue siendo `True`.
42. Explica c贸mo convertir un string a entero o a n煤mero decimal en Python. 驴Qu茅 pasa si el string no puede convertirse? #### Python Para convertir, usa `int()` y `float()`: ```python count = int("42") ratio = float("3.14") ``` Si el string no es v谩lido, Python lanza `ValueError`. ```python def parse_int(value: str) -> int | None: try: return int(value) except ValueError: return None ``` **En resumen:** - `int()` y `float()` realizan una conversi贸n expl铆cita desde string. - Un formato inv谩lido produce `ValueError`. - Para datos externos, hace falta `try/except`.
43. 驴Qu茅 hace Python al comparar distintos tipos de datos, como enteros y flotantes, o enteros y booleanos? #### Python Python permite comparaciones num茅ricas entre numeric types compatibles. - `int` y `float` se comparan por valor. - `bool` es una subclase de `int`: `False == 0`, `True == 1`. ```python 1 == 1.0 # True True == 1 # True False < 1 # True ``` Para tipos incompatibles como `int` y `str`, las comparaciones de orden como `<` y `>` lanzan `TypeError`. **En resumen:** - `int`, `float` y `bool` comparten una sem谩ntica num茅rica com煤n. - `bool` se comporta como `0/1` en comparaciones. - Los tipos incompatibles no se comparan con operadores de orden.
44. 驴C贸mo maneja Python la comparaci贸n entre listas y sets? #### Python `list` y `set` son tipos distintos con sem谩nticas diferentes, por lo que la comparaci贸n directa de orden entre ellos no est谩 soportada. ```python [1, 2] == {1, 2} # False [1, 2] < {1, 2} # TypeError ``` Si necesitas comparar el contenido de elementos, primero normaliza el tipo: ```python set([1, 2]) == {1, 2} # True ``` **En resumen:** - `list` y `set` se comparan como estructuras de datos distintas. - `==` entre ellas normalmente da `False`. - Para una comparaci贸n con sentido, primero convi茅rtelas al mismo tipo.
45. Describe el uso de la funci贸n `bool()` en Python. #### Python `bool(x)` devuelve el valor booleano de `x` seg煤n las reglas de truthiness. Escenarios t铆picos: - conversi贸n expl铆cita de un valor a `True/False`; - condiciones m谩s legibles; - construcci贸n de filtros. ```python bool("text") # True bool("") # False bool(0) # False ``` **En resumen:** - `bool()` unifica la comprobaci贸n de "vac铆o/no vac铆o". - Se basa en las reglas integradas de truthy/falsy. - Es 煤til para validaci贸n y l贸gica condicional.
46. 驴Cu谩l es la diferencia entre `list` y `tuple`? #### Python La diferencia principal es que `list` es mutable y `tuple` es immutable. Consecuencias pr谩cticas: - `list` sirve para datos que cambian; - `tuple` sirve para registros fijos; - `tuple` puede usarse como clave de diccionario si sus elementos son hashables. ```python coords: tuple[float, float] = (50.45, 30.52) queue: list[str] = ["task-1", "task-2"] ``` **En resumen:** - `list` es para colecciones mutables. - `tuple` es para estructuras de datos inmutables. - La elecci贸n afecta la seguridad de la API y su uso en `dict/set`.
47. 驴C贸mo se puede crear un `tuple`? #### Python Formas principales: ```python t1 = (1, 2, 3) t2 = 1, 2, 3 t3 = tuple([1, 2, 3]) single = (42,) # la coma es importante empty = () ``` Para un solo elemento, la coma es obligatoria; de lo contrario, es solo una expresi贸n entre par茅ntesis. **En resumen:** - Un `tuple` se crea con un literal o con `tuple(iterable)`. - `single = (x,)` es un tuple v谩lido de un solo elemento. - El tuple vac铆o es `()`.
48. 驴Cu谩l es la diferencia entre el m茅todo `reverse` y el slicing `[::-1]` al invertir una lista? #### Python `list.reverse()` modifica la lista existente in-place y devuelve `None`. `lst[::-1]` crea una nueva lista invertida, es decir, una copia. ```python values = [1, 2, 3] values.reverse() # values -> [3, 2, 1] other = values[::-1] # nueva lista ``` **En resumen:** - `reverse()` modifica el original. - `[::-1]` devuelve un objeto nuevo. - La elecci贸n depende de si necesitas conservar los datos originales.
49. Explica el prop贸sito y el uso del m茅todo `sort` para listas. 驴C贸mo ordenar una lista en orden descendente? #### Python `list.sort()` ordena la lista in-place. Soporta estos par谩metros: - `key`, una funci贸n de clave de ordenaci贸n; - `reverse=True`, para orden descendente. ```python nums = [5, 1, 7] nums.sort(reverse=True) # [7, 5, 1] ``` Si necesitas una copia nueva ordenada, usa `sorted(iterable)`. **En resumen:** - `sort()` modifica la lista en el lugar. - Para orden descendente, usa `reverse=True`. - `sorted()` es conveniente cuando necesitas conservar el original.
50. 驴Cu谩l es la diferencia entre el m茅todo `copy` y la asignaci贸n directa de una lista a otra? 驴Por qu茅 a veces es importante usar `copy`? #### Python La asignaci贸n copia solo la referencia: ```python a = [1, 2] b = a b.append(3) # a tambi茅n cambiar谩 ``` `a.copy()` crea una lista nueva, superficial: ```python a = [1, 2] b = a.copy() b.append(3) # a no cambiar谩 ``` Para estructuras anidadas, puede hacer falta `copy.deepcopy`. **En resumen:** - `=` no copia los datos; comparte el mismo objeto entre variables. - `copy()` a铆sla los cambios a nivel de la lista superior. - Para objetos anidados, usa `deepcopy`.
51. 驴Qu茅 hace el m茅todo `pop` en una lista? 驴En qu茅 se diferencia su comportamiento si se indica un 铆ndice o no? #### Python `pop()` elimina y devuelve un elemento de la lista. - `pop()` sin argumentos elimina el 煤ltimo elemento; - `pop(i)` elimina el elemento con 铆ndice `i`. ```python items = ["a", "b", "c"] last = items.pop() # "c" first = items.pop(0) # "a" ``` Un 铆ndice inv谩lido produce `IndexError`. **En resumen:** - `pop` combina eliminaci贸n y devoluci贸n del valor. - Sin 铆ndice, trabaja sobre el final de la lista. - Con 铆ndice, elimina una posici贸n concreta.
52. 驴C贸mo unir dos listas en Python usando el operador `+` y el m茅todo `extend`? 驴Cu谩l es la diferencia clave entre ambos enfoques? #### Python `a + b` crea una **nueva** lista, mientras que `a.extend(b)` modifica la lista `a` **in-place**. ```python a = [1, 2] b = [3, 4] c = a + b # [1, 2, 3, 4], a no cambi贸 a.extend(b) # a -> [1, 2, 3, 4] ``` **En resumen:** - `+` devuelve un objeto nuevo. - `extend()` muta la lista existente. - La elecci贸n depende de si necesitas conservar el original.
53. 驴Para qu茅 se usan las funciones `min`, `max`, `sum`, `all` y `any` en el contexto de listas? #### Python Son agregadores b谩sicos para colecciones iterables: - `min()` / `max()` para m铆nimo y m谩ximo; - `sum()` para suma de n煤meros; - `all()` devuelve `True` si todos los elementos son truthy; - `any()` devuelve `True` si al menos un elemento es truthy. ```python nums = [3, 10, 1] min(nums), max(nums), sum(nums) # (1, 10, 14) all([True, 1, "x"]) # True any([0, "", None, 5]) # True ``` **En resumen:** - Estas funciones reducen el c贸digo repetitivo en los bucles. - Funcionan con cualquier iterable. - Combinan bien con generadores para procesamiento perezoso.
54. 驴Qu茅 es un diccionario (`dict`) en Python y en qu茅 se diferencia de otras estructuras de datos? #### Python `dict` es un array asociativo que almacena pares `clave -> valor`. Las claves deben ser hashable y los valores pueden ser de cualquier tipo. Diferencias: - acceso por clave y no por 铆ndice; - complejidad media de b煤squeda, inserci贸n y eliminaci贸n cercana a `O(1)`; - desde Python 3.7+ conserva el orden de inserci贸n de las claves. **En resumen:** - `dict` es 贸ptimo para acceso r谩pido por clave. - Es la estructura principal para configuraciones y mappings. - Las claves deben ser inmutables y hashable.
55. 驴Cu谩l es la diferencia entre obtener un valor de un diccionario con corchetes `[]` y con el m茅todo `get`? #### Python `d[key]` devuelve el valor o lanza `KeyError` si la clave no existe. `d.get(key, default)` devuelve el valor o `default`, o `None`, sin lanzar excepci贸n. ```python config = {"timeout": 30} config["timeout"] # 30 config.get("retries", 3) # 3 ``` **En resumen:** - `[]` sirve para claves obligatorias. - `get()` sirve para campos opcionales. - `get()` reduce la necesidad de `try/except` al leer datos.
56. Describe c贸mo se pueden actualizar y eliminar elementos de un diccionario. #### Python Actualizaci贸n: - `d[key] = value` inserta o actualiza una sola clave; - `d.update({...})` hace una actualizaci贸n masiva. Eliminaci贸n: - `del d[key]` elimina una clave, con error si no existe; - `d.pop(key, default)` elimina y devuelve el valor; - `d.popitem()` elimina el 煤ltimo par; - `d.clear()` limpia todo el diccionario. **En resumen:** - Para upsert, sirven `[]` y `update()`. - Para eliminaci贸n segura, suele usarse `pop()`. - Elige la API seg煤n el comportamiento deseado si la clave falta.
57. 驴Para qu茅 sirven los m茅todos `keys`, `values` e `items` en los diccionarios? #### Python Estos m茅todos devuelven objetos vista del diccionario: - `keys()` devuelve todas las claves; - `values()` devuelve todos los valores; - `items()` devuelve pares `(key, value)`. ```python data = {"a": 1, "b": 2} for key, value in data.items(): ... ``` Las vistas son din谩micas: reflejan el estado actual del diccionario. **En resumen:** - `keys/values/items` sirven para iteraci贸n y comprobaciones. - `items()` es lo m谩s c贸modo para recorrer clave y valor en un bucle. - No son copias, sino vistas "vivas" de los datos.
58. 驴C贸mo est谩 implementado `dict` internamente en Python? #### Python `dict` est谩 implementado como una hash table optimizada para memoria y acceso r谩pido. La clave se hashea, se elige una celda por el hash y las colisiones se resuelven con un algoritmo interno de probing. Consecuencias pr谩cticas: - el acceso medio es cercano a `O(1)`; - la calidad de `__hash__` y `__eq__` influye en el comportamiento; - los objetos mutables no pueden usarse como claves. **En resumen:** - `dict` es una estructura hash de alto rendimiento. - Su velocidad se consigue gracias al hash. - Las claves deben ser hashable y estables.
59. 驴Qu茅 es una hash function? #### Python Una hash function transforma un objeto en un n煤mero entero, el hash, que se usa para ubicarlo o buscarlo r谩pidamente en `dict` y `set`. Condiciones de correcci贸n: - si `a == b`, entonces `hash(a) == hash(b)`; - el valor del hash debe ser estable durante la vida del objeto. **En resumen:** - La hash function es la base del rendimiento r谩pido de `dict` y `set`. - No garantiza unicidad, porque puede haber colisiones. - En clases personalizadas, `__eq__` y `__hash__` deben ser coherentes.
60. 驴Qu茅 es `set` en Python y en qu茅 se diferencia de otras estructuras de datos? #### Python `set` es una colecci贸n no ordenada de elementos **煤nicos**. Diferencias: - elimina duplicados autom谩ticamente; - ofrece operaciones r谩pidas de pertenencia, `x in s`; - soporta operaciones de teor铆a de conjuntos como uni贸n, intersecci贸n y diferencia. **En resumen:** - `set` es 贸ptimo para unicidad y membership checks. - El orden de los elementos no est谩 garantizado. - Los elementos deben ser hashable.
61. 驴C贸mo crear un `set` en Python y qu茅 restricciones existen para sus elementos? #### Python Creaci贸n: ```python s1 = {1, 2, 3} s2 = set([1, 2, 2, 3]) # {1, 2, 3} empty = set() # no {} ``` Restricciones: - los elementos deben ser hashable, por ejemplo `int`, `str`, `tuple`; - `list`, `dict` y `set` no pueden a帽adirse directamente. **En resumen:** - `set()` crea un conjunto vac铆o. - Los duplicados se eliminan autom谩ticamente. - Solo se permiten elementos hashable.
62. 驴Para qu茅 se usa el m茅todo `intersection()` en un set de Python y en qu茅 se diferencia de `union()`? #### Python `intersection()` devuelve los elementos comunes entre conjuntos, mientras que `union()` re煤ne todos los elementos 煤nicos de ambos conjuntos. ```python a = {1, 2, 3} b = {3, 4} a.intersection(b) # {3} a.union(b) # {1, 2, 3, 4} ``` **En resumen:** - `intersection` equivale a intersecci贸n, lo com煤n. - `union` equivale a uni贸n, todo lo 煤nico. - Ambos m茅todos son b谩sicos para comparar conjuntos de datos.
63. 驴Qu茅 tipos de datos son immutable? #### Python Tipos immutable comunes: - `int`, `float`, `bool`, `complex`; - `str`, `bytes`; - `tuple`, si sus elementos tambi茅n son immutable; - `frozenset`; - `NoneType`. **En resumen:** - Un objeto immutable no puede cambiar despu茅s de crearse. - En lugar de mutarlo, se crea un objeto nuevo. - Estos tipos son m谩s seguros como claves de `dict` y elementos de `set`.
64. 驴Qu茅 tipos de datos son mutable? #### Python Tipos mutable comunes: - `list`; - `dict`; - `set`; - `bytearray`; - la mayor铆a de objetos de clases definidas por el usuario. **En resumen:** - Los objetos mutable cambian in-place. - Las mutaciones pueden generar efectos secundarios por referencias compartidas. - Hay que tener cuidado con las copias.
65. 驴Por qu茅 es importante entender la mutabilidad al trabajar con diccionarios o sets? #### Python `dict` y `set` se basan en hashing, por lo que sus claves y elementos deben ser estables y hashable. Los objetos mutable no pueden usarse con seguridad como claves o elementos de un set. Adem谩s, mutar valores a trav茅s de referencias compartidas suele producir bugs inesperados. **En resumen:** - La mutability afecta la correcci贸n de claves en `dict` y `set`. - Los objetos mutable compartidos suelen causar efectos secundarios. - Las copias expl铆citas y el control de mutaciones reducen bugs.
66. 驴Qu茅 es `None`? #### Python `None` es un valor singleton especial del tipo `NoneType` que significa "ausencia de valor". Escenarios t铆picos: - una funci贸n no devuelve nada expl铆citamente; - par谩metros opcionales; - marcador de "dato a煤n no definido". La comprobaci贸n se hace con `is`: ```python if value is None: ... ``` **En resumen:** - `None` significa ausencia de valor. - Es un singleton, por eso se compara con `is`. - Se usa a menudo en APIs como estado opcional.
67. 驴Qu茅 es `id` en Python, c贸mo se usa y por qu茅 es importante? #### Python `id(obj)` devuelve el identificador del objeto, 煤nico dentro del ciclo de vida del objeto en el proceso actual. Es 煤til para diagn贸stico: - saber si es el mismo objeto; - verificar si se cre贸 una copia; - detectar si hubo mutaci贸n de una referencia compartida. **En resumen:** - `id` ayuda a analizar la identidad de los objetos. - Es 煤til al depurar copias y mutaciones. - No se usa como identificador de negocio.
68. 驴Cu谩l es la diferencia entre los operadores `is` y `==`? #### Python `==` compara **valores**, es decir equivalencia, mientras que `is` compara **identidad**, o sea si se trata del mismo objeto en memoria. ```python a = [1, 2] b = [1, 2] a == b # True a is b # False ``` **Importante sobre optimizaciones, interning:** CPython cachea enteros peque帽os de `-5` a `256` y strings cortos durante compilaci贸n o carga. Por eso, `is` puede devolver `True` incluso si parecen creados por separado. Pero esto es un detalle de implementaci贸n y no debe usarse en l贸gica de negocio. Para `None`, usa siempre `is`. **En resumen:** - `==` trata sobre igualdad de valores. - `is` trata sobre el mismo objeto en memoria. - El interning puede producir un `is True` inesperado para `int` y `str` peque帽os. - `value is None` es la 煤nica forma correcta de comprobar `None`.
69. 驴C贸mo se aplica el patr贸n Singleton en Python? Da ejemplos de objetos de instancia 煤nica en Python. #### Python Singleton significa una sola instancia global de un objeto dentro del proceso. En Python, a menudo se sustituye por el nivel de m贸dulo, ya que los m贸dulos se importan una sola vez. Ejemplos de objetos de instancia 煤nica del lenguaje: - `None`; - `True` y `False`; - `Ellipsis`. En c贸digo de aplicaci贸n, en lugar de un Singleton r铆gido, suele preferirse un contenedor de DI o factor铆as para mejorar la testabilidad. **En resumen:** - Python ya tiene objetos de instancia 煤nica integrados. - A menudo basta con el alcance de m贸dulo sin aplicar un patr贸n separado. - Abusar de Singleton empeora la testabilidad.
70. 驴Para qu茅 se usan los operadores `break` y `continue` en los bucles de Python? #### Python `break` finaliza el bucle de forma anticipada, mientras que `continue` omite la iteraci贸n actual y pasa a la siguiente. ```python for n in range(10): if n == 5: break if n % 2 == 0: continue ``` **En resumen:** - `break` detiene el bucle por completo. - `continue` omite solo el paso actual. - Hacen que el control del bucle sea expl铆cito y legible.
71. Explica el concepto de un bucle infinito. 驴Cu谩ndo es apropiado usarlo y c贸mo asegurar su terminaci贸n correcta? #### Python Un bucle infinito es un bucle sin una condici贸n natural de finalizaci贸n, por ejemplo `while True`. Se usa para procesos en segundo plano o de trabajo, sondeo y l贸gica de bucle de eventos. Terminaci贸n correcta: - una condici贸n `break` clara; - manejo de se帽ales de terminaci贸n; - tiempos de espera y `try/finally` para la limpieza final. ```python while True: task = queue.get() if task is None: break handle(task) ``` **En resumen:** - `while True` es adecuado para bucles de servicio de larga duraci贸n. - Hace falta un mecanismo de parada controlado. - Siempre hay que prever la liberaci贸n de recursos.
72. Describe c贸mo funcionan los bucles anidados en Python. 驴Qu茅 problemas de rendimiento pueden causar y c贸mo evitarlos? #### Python Un bucle anidado es un bucle dentro de otro. La complejidad suele convertirse en `O(n*m)` o peor, lo que resulta cr铆tico con grandes vol煤menes de datos. Optimizaciones: - sustituir b煤squedas en listas por `set` o `dict`; - sacar los invariantes fuera del bucle interno; - usar generadores, `itertools` y vectorizaci贸n; - perfilar las zonas calientes. **En resumen:** - Los bucles anidados multiplican r谩pidamente el coste computacional. - Las estructuras de datos suelen ser m谩s importantes que las microoptimizaciones. - El perfilado muestra exactamente qu茅 debe optimizarse.
73. 驴Qu茅 es la coincidencia estructural de patrones (`match`/`case`)? #### Python `match/case` en Python 3.10+ es un mecanismo para analizar estructuras de datos mediante patrones. Funciona con literales, tipos, secuencias, diccionarios y clases. ```python def handle(message: dict[str, object]) -> str: match message: case {"type": "ping"}: return "pong" case {"type": "user", "id": int(user_id)}: return f"user:{user_id}" case _: return "unknown" ``` **En resumen:** - `match/case` se lee mejor en ramificaciones complejas. - Permite comprobar la forma y extraer datos al mismo tiempo. - Es especialmente 煤til para protocolos, eventos y parsing de estructuras.
74. 驴En qu茅 casos la coincidencia de patrones es mejor que `if`/`elif`? #### Python `match/case` es mejor cuando necesitas: - comprobar muchas formas de datos mutuamente excluyentes; - desempaquetar estructuras anidadas; - evitar cadenas largas de `if/elif`. `if/elif` es mejor para condiciones booleanas simples y l贸gica breve. **En resumen:** - Para escenarios estructurales, es mejor `match/case`. - Para condiciones simples, basta con `if/elif`. - El criterio de elecci贸n es la legibilidad y el mantenimiento.
75. 驴Qu茅 es una funci贸n en Python? #### Python Una funci贸n es un bloque de c贸digo invocable con nombre que recibe argumentos, devuelve un resultado y permite encapsular l贸gica. ```python def normalize_name(name: str) -> str: return name.strip().title() ``` Las funciones soportan valores por defecto, argumentos nombrados, `*args/**kwargs`, anotaciones de tipos y decoradores. **En resumen:** - La funci贸n es la unidad b谩sica de reutilizaci贸n de c贸digo. - Define un contrato claro mediante par谩metros y valor de retorno. - Las anotaciones de tipos hacen expl铆cito ese contrato.
76. 驴Qu茅 tipos de argumentos de funci贸n existen? #### Python En Python moderno: - positional-only (`/`); - posicional o nombrado; - solo nombrado (`*`); - variadic positional (`*args`); - variadic keyword (`**kwargs`). ```python def f(a, /, b, *, c, **kwargs): ... ``` **En resumen:** - Python ofrece un control flexible sobre c贸mo se llama una funci贸n. - `/` y `*` formalizan el contrato de la API. - `*args/**kwargs` son 煤tiles para interfaces extensibles.
77. 驴Qu茅 son los argumentos posicionales y los argumentos nombrados? #### Python Los argumentos posicionales se pasan por orden, y los argumentos nombrados se pasan por nombre del par谩metro. ```python def connect(host: str, port: int) -> str: return f"{host}:{port}" connect("localhost", 5432) # posicional connect(host="localhost", port=5432) # nombrado ``` **En resumen:** - Los posicionales dependen del orden de los par谩metros. - Los nombrados mejoran la legibilidad de la llamada. - Se pueden combinar respetando las reglas de la firma.
78. 驴Qu茅 son los argumentos por defecto y qu茅 problemas pueden tener? #### Python Los argumentos por defecto se usan cuando no se pasa un valor en la llamada. Se eval煤an **una sola vez** al definir la funci贸n. Problema: valor mutable por defecto. ```python def add_item(item: int, bucket: list[int] | None = None) -> list[int]: if bucket is None: bucket = [] bucket.append(item) return bucket ``` **En resumen:** - Los valores por defecto son c贸modos para valores estables. - Un valor mutable por defecto puede acumular estado entre llamadas. - El patr贸n seguro es `None` m谩s inicializaci贸n interna.
79. Explica el prop贸sito y uso de `*args` y `**kwargs` en funciones de Python. 驴En qu茅 se diferencian? #### Python `*args` recoge argumentos posicionales adicionales en un `tuple`. `**kwargs` recoge argumentos nombrados adicionales en un `dict`. ```python def log_event(event: str, *args: object, **kwargs: object) -> None: ... ``` Usos t铆picos: envoltorios, adaptadores de API, decoradores y reenv铆o de par谩metros. **En resumen:** - `*args` significa posicionales adicionales. - `**kwargs` significa nombrados adicionales. - Hacen las funciones m谩s flexibles, pero requieren validaci贸n clara.
80. 驴C贸mo definir una funci贸n con anotaciones de tipos en Python? Da un ejemplo y explica las ventajas de este enfoque. #### Python Los tipos se indican en la firma de los par谩metros y en el valor de retorno. ```python def process_users(users: list[dict[str, object]]) -> list[str]: return [str(user["name"]) for user in users if bool(user.get("active"))] ``` Ventajas: - mejor experiencia de desarrollo, como autocompletado y navegaci贸n; - comprobaci贸n est谩tica en CI; - contrato expl铆cito para otros desarrolladores. **En resumen:** - Las anotaciones de tipos documentan la API. - Reducen el riesgo de errores de integraci贸n. - Aportan m谩s valor en bases de c贸digo medianas y grandes.
81. 驴Qu茅 son las funciones lambda? #### Python `lambda` es una funci贸n an贸nima de una sola expresi贸n. Normalmente se usa para funciones de devoluci贸n de llamada cortas en `sorted`, `map` y `filter`. ```python users = [{"name": "Ada"}, {"name": "Bob"}] users_sorted = sorted(users, key=lambda u: u["name"]) ``` Para l贸gica compleja, es mejor una funci贸n normal definida con `def`. **En resumen:** - `lambda` es c贸moda para expresiones locales cortas. - Est谩 limitada a una sola expresi贸n. - Para mantener la legibilidad, el c贸digo complejo debe ir en una `def`.
82. 驴Cu谩l es el alcance de las variables dentro de una funci贸n? #### Python Python usa la regla LEGB para buscar nombres: - `L`ocal; - `E`nclosing, funciones externas; - `G`lobal, m贸dulo; - `B`uiltins, nombres integrados. Dentro de una funci贸n, una asignaci贸n crea una variable local si no se declara `global` o `nonlocal`. **En resumen:** - El alcance define d贸nde un nombre est谩 disponible y puede modificarse. - LEGB explica el orden de b煤squeda de variables. - Entender mal el alcance suele provocar `UnboundLocalError`.
83. 驴Qu茅 son las variables locales y globales en Python? #### Python Las variables locales viven dentro del cuerpo de una funci贸n. Las variables globales se definen a nivel de m贸dulo. Para modificar una global desde una funci贸n hace falta `global`, pero normalmente conviene evitarlo por las dependencias impl铆citas que crea. **En resumen:** - Las locales son m谩s seguras para mantenimiento y pruebas. - Las globales simplifican el acceso, pero complican el control del estado. - Es mejor pasar las dependencias como par谩metros.
84. 驴Cu谩l es la diferencia entre variables locales y nonlocal en Python? #### Python `nonlocal` se usa dentro de una funci贸n anidada para modificar una variable del alcance envolvente m谩s cercano, no del alcance global. ```python from collections.abc import Callable def counter() -> Callable: value = 0 def inc() -> int: nonlocal value value += 1 return value return inc ``` **En resumen:** - Una variable local pertenece a la funci贸n actual. - `nonlocal` modifica el estado de la funci贸n externa. - Es un mecanismo clave para cierres con estado.
85. 驴Qu茅 es el desempaquetado en Python y c贸mo se aplica en asignaciones? #### Python El desempaquetado es descomponer los elementos de una secuencia o estructura en variables separadas. ```python x, y = (10, 20) first, *middle, last = [1, 2, 3, 4] ``` Tambi茅n funciona con diccionarios en `match/case`, en llamadas de funciones y en bucles. **En resumen:** - El desempaquetado hace el c贸digo m谩s compacto y legible. - Soporta la captura del resto de valores con el operador estrella. - Se usa a menudo al parsear estructuras de datos.
86. Explica el concepto de empaquetado de valores en Python y da ejemplos. #### Python El empaquetado es reunir varios valores en una sola estructura como `tuple`, `list` o `dict`. ```python point = 10, 20 # empaquetado en tuple def collect(*args: int) -> tuple[int, ...]: return args ``` `*args` y `**kwargs` son ejemplos t铆picos de empaquetado de argumentos. **En resumen:** - El empaquetado re煤ne muchos valores en un solo contenedor. - Se usa con mucha frecuencia en firmas de funciones. - Combina bien con el desempaquetado del lado de la llamada.
87. 驴Para qu茅 se usa el operador `*` en el empaquetado y desempaquetado? #### Python En par谩metros de funci贸n, `*` empaqueta argumentos posicionales en `*args`, y en la llamada desempaqueta un iterable en argumentos posicionales. ```python def add(a: int, b: int) -> int: return a + b nums = [2, 3] add(*nums) # 5 ``` Tambi茅n se usa en asignaciones para capturar "el resto" de los elementos. **En resumen:** - `*` es un operador universal para trabajar con argumentos variables. - En la firma empaqueta y en la llamada desempaqueta. - Reduce el c贸digo repetitivo al pasar datos.
88. 驴Qu茅 es un cierre y qu茅 relaci贸n tiene con los decoradores? #### Python Un cierre es una funci贸n interna que "recuerda" las variables del alcance envolvente incluso despu茅s de que la funci贸n externa haya terminado. Un decorador suele implementarse precisamente mediante un cierre: la envoltura conserva una referencia a la funci贸n original y a par谩metros adicionales. **En resumen:** - Un cierre es funci贸n m谩s contexto capturado. - Un decorador suele ser una aplicaci贸n pr谩ctica de un cierre. - Permite a帽adir comportamiento sin cambiar el cuerpo de la funci贸n.
89. 驴Qu茅 es un decorador en Python y c贸mo funciona? #### Python Un decorador es un objeto invocable que recibe una funci贸n o clase y devuelve una versi贸n modificada, una envoltura. ```python from functools import wraps def log_calls(func): @wraps(func) def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper ``` Aplicaciones t铆picas: registro, cach茅, autorizaci贸n, reintentos y m茅tricas. **En resumen:** - Un decorador a帽ade comportamiento transversal. - Funciona envolviendo un objeto invocable. - Evita duplicar l贸gica t茅cnica dentro del c贸digo de negocio.
90. 驴Se pueden usar varios decoradores en una misma funci贸n? #### Python S铆, se pueden apilar varios decoradores. Se aplican de abajo hacia arriba: el m谩s cercano a `def` envuelve primero. ```python @decorator_a @decorator_b def handler() -> None: ... ``` Equivalente: `handler = decorator_a(decorator_b(handler))`. **En resumen:** - Usar varios decoradores es v谩lido y com煤n. - El orden de aplicaci贸n importa. - La pila de decoradores debe documentarse para mantener claridad.
91. Describe un posible problema con el orden de los decoradores al aplicarlos a una funci贸n. #### Python Un orden incorrecto puede cambiar la sem谩ntica: por ejemplo, aplicar cach茅 antes de una comprobaci贸n de acceso puede almacenar un resultado no deseado o saltarse la l贸gica esperada. Riesgos t铆picos: - el registro ve argumentos ya modificados; - los reintentos envuelven la excepci贸n equivocada; - la cach茅 se aplica antes o despu茅s de la validaci贸n en el punto incorrecto. **En resumen:** - El orden de los decoradores afecta al comportamiento de la funci贸n. - Es una causa frecuente de bugs ocultos. - Las cadenas cr铆ticas necesitan pruebas sobre el orden de ejecuci贸n.
92. 驴Se puede crear un decorador con una clase? #### Python S铆. Una clase decoradora implementa `__call__` para que su instancia se comporte como una funci贸n. ```python class CallCounter: def __init__(self, func): self.func = func self.calls = 0 def __call__(self, *args, **kwargs): self.calls += 1 return self.func(*args, **kwargs) ``` **En resumen:** - Un decorador puede implementarse no solo con una funci贸n, sino tambi茅n con una clase. - La clase es 煤til cuando se necesita estado interno. - El mecanismo clave es `__call__`.
93. 驴C贸mo definir un decorador que acepta par谩metros? #### Python Hace falta una estructura de tres niveles: f谩brica de decoradores, decorador y envoltura. ```python from functools import wraps def retry(times: int): def decorator(func): @wraps(func) def wrapper(*args, **kwargs): for _ in range(times - 1): try: return func(*args, **kwargs) except Exception: pass return func(*args, **kwargs) return wrapper return decorator ``` **En resumen:** - Un decorador parametrizado es una funci贸n que devuelve otro decorador. - A menudo se usa un cierre para conservar los par谩metros. - Este enfoque es c贸modo para comportamiento configurable.
94. 驴Para qu茅 se usa `functools.wraps` en funciones decoradoras? #### Python `functools.wraps` copia los metadatos de la funci贸n original a la envoltura: nombre, docstring, m贸dulo y tambi茅n `__wrapped__`. Esto es importante para: - depuraci贸n y logs correctos; - introspecci贸n y documentaci贸n; - compatibilidad con herramientas que leen la firma. **En resumen:** - `wraps` conserva la "identidad" de la funci贸n original. - Sin 茅l, las funciones decoradas pierden metadatos 煤tiles. - Es una buena pr谩ctica para todos los decoradores de envoltura.
95. 驴C贸mo funcionan dict comprehension, list comprehension y set comprehension? #### Python Una comprehension crea una colecci贸n a partir de una expresi贸n y uno o varios bucles, opcionalmente con filtro. ```python squares = [x * x for x in range(6)] mapping = {x: x * x for x in range(6)} unique = {x % 3 for x in range(10)} ``` Formato: - list: `[expr for x in it if cond]` - set: `{expr for x in it if cond}` - dict: `{k_expr: v_expr for x in it if cond}` **En resumen:** - Una comprehension expresa transformaciones de datos de forma compacta. - Funciona con `list`, `set` y `dict`. - Produce un c贸digo m谩s limpio que agregar elementos manualmente en un bucle.
96. 驴Qu茅 ventajas tienen las list comprehensions frente a los bucles normales? #### Python Ventajas: - c贸digo m谩s corto y declarativo; - menos variables auxiliares; - normalmente un poco mejor de rendimiento en CPython; - menor riesgo de olvidar `append`. Desventaja: para l贸gica muy compleja, una comprehension empeora la legibilidad. **En resumen:** - Una list comprehension es ideal para transformaciones simples. - A menudo es m谩s r谩pida y m谩s limpia que un bucle manual. - Para ramas complejas, es mejor un `for` normal.
97. 驴Puedes dar un ejemplo de una list comprehension anidada? #### Python Ejemplo de flatten de una matriz: ```python matrix = [[1, 2], [3, 4], [5, 6]] flat = [item for row in matrix for item in row] # [1, 2, 3, 4, 5, 6] ``` Ejemplo con condici贸n: ```python pairs = [(x, y) for x in range(3) for y in range(3) if x != y] ``` **En resumen:** - Una comprehension anidada son varios `for` dentro de una sola expresi贸n. - El orden de los `for` corresponde al de los bucles anidados. - 脷sala cuando la expresi贸n siga siendo legible.
98. 驴Qu茅 es m谩s r谩pido en Python: una list comprehension o crear una lista con un bucle? #### Python En escenarios t铆picos, una list comprehension es un poco m谩s r谩pida que un bucle con `append`, porque tiene bytecode optimizado y menos sobrecarga. Importante: la mejora real depende del cuerpo de la operaci贸n, as铆 que en zonas cr铆ticas conviene medir con `timeit` o `pyperf`. **En resumen:** - A menudo la list comprehension es m谩s r谩pida. - La diferencia puede ser peque帽a. - Para decisiones de producci贸n, gu铆ate por mediciones.
99. 驴Qu茅 es un iterador en Python? #### Python Un iterador es un objeto que devuelve elementos secuencialmente y recuerda su estado actual. Implementa el protocolo: - `__iter__()` devuelve a s铆 mismo; - `__next__()` devuelve el siguiente elemento o lanza `StopIteration`. **En resumen:** - Un iterador da acceso elemento por elemento sin cargar todos los datos. - Es la base de `for`, de los generadores y del procesamiento perezoso. - Una vez agotado, un iterador no se reinicia solo.
100. 驴C贸mo crear un iterador a partir de un objeto iterable usando la funci贸n `iter()`? #### Python Llama a `iter(iterable)` para obtener un iterador. ```python items = [10, 20, 30] it = iter(items) ``` Despu茅s de eso, los valores se leen con `next(it)`. **En resumen:** - `iter()` convierte un iterable en un iterador. - Es una forma expl铆cita de controlar la iteraci贸n manualmente. - Se usa en procesamiento de flujos de datos a bajo nivel.
101. 驴Para qu茅 sirve la funci贸n `next()` al trabajar con iterators? #### Python `next(iterator[, default])` devuelve el siguiente elemento del iterador. Cuando los elementos se han agotado, lanza `StopIteration` o devuelve `default` si se ha pasado. ```python it = iter([1, 2]) next(it) # 1 next(it) # 2 next(it, None) # None ``` **En resumen:** - `next()` da control manual sobre cada paso de la iteraci贸n. - Sin `default`, el final del flujo produce `StopIteration`. - Con `default`, se puede leer el flujo de forma segura.
102. 驴Se pueden usar de forma intercambiable los m茅todos `__next__()` y `__iter__()` con las funciones `next()` e `iter()`? #### Python S铆, pero con el matiz del protocolo: - `iter(obj)` llama a `obj.__iter__()`; - `next(it)` llama a `it.__next__()`. Es decir, estas funciones son la interfaz est谩ndar para los m茅todos dunder y normalmente se usan en lugar de invocarlos directamente. **En resumen:** - `iter()` corresponde a `__iter__()`. - `next()` corresponde a `__next__()`. - En c贸digo de aplicaci贸n, es mejor usar las funciones integradas.
103. 驴Qu茅 papel tiene `StopIteration` en el dise帽o de iterators y cu谩ndo suele aparecer? #### Python `StopIteration` indica que el iterador se ha agotado. El bucle `for` lo captura autom谩ticamente y finaliza la iteraci贸n. Normalmente aparece: - al llamar a `next(it)` despu茅s del 煤ltimo elemento; - en iterators personalizados, cuando los datos se terminan. **En resumen:** - `StopIteration` es el final normal del flujo. - No debe registrarse como "error" dentro del flujo normal. - En iterators propios, debe lanzarse correctamente.
104. 驴Qu茅 es un generador y en qu茅 se diferencia de un iterador o de una funci贸n normal? #### Python Un generador es un iterador especial que se crea con una funci贸n que usa `yield`. Genera valores uno por uno y conserva su estado interno entre llamadas. Diferencias: - frente a una funci贸n normal: no termina con un 煤nico `return`, sino que funciona con "pausa/reanudaci贸n"; - frente a un iterador manual: tiene una implementaci贸n m谩s simple, sin una clase expl铆cita con `__next__`. **En resumen:** - Un generador es la forma m谩s c贸moda de hacer iteraci贸n perezosa. - Requiere menos c贸digo que una clase iteradora personalizada. - Es especialmente 煤til para grandes flujos de datos.
105. 驴C贸mo se crea una funci贸n generadora? #### Python Hay que definir una funci贸n con `yield`. ```python def countdown(start: int): current = start while current > 0: yield current current -= 1 ``` La llamada `countdown(3)` devuelve un objeto generador que se puede iterar. **En resumen:** - La presencia de `yield` convierte la funci贸n en un generador. - Un generador devuelve valores por etapas. - El estado de la funci贸n se conserva entre iteraciones.
106. 驴C贸mo proporciona la palabra clave `yield` la funcionalidad de los generadores y por qu茅 ahorran memoria? #### Python `yield` devuelve el siguiente valor y "congela" el contexto de la funci贸n (variables locales, posici贸n de ejecuci贸n). El siguiente `next()` reanuda la ejecuci贸n desde ese punto. El ahorro de memoria se debe a que los datos no se crean por completo de antemano, sino que se calculan bajo demanda. **En resumen:** - `yield` implementa la pausa y la reanudaci贸n de la ejecuci贸n. - Un generador soporta evaluaci贸n perezosa. - Esto reduce el consumo de memoria en conjuntos de datos grandes.
107. 驴Cu谩l es la diferencia entre `return` y `yield`? #### Python `return` finaliza la funci贸n y devuelve un 煤nico valor final. `yield` devuelve un valor intermedio y conserva el estado para poder continuar despu茅s. En un generador, `return` significa el final de la iteraci贸n (`StopIteration`). **En resumen:** - `return` -> finalizaci贸n de la funci贸n. - `yield` -> entrega de valores por etapas. - `yield` se usa para procesamiento en flujo.
108. 驴Qu茅 es la programaci贸n orientada a objetos (POO) y cu谩les son sus principios principales en Python? #### Python La POO es un enfoque en el que los datos y el comportamiento se agrupan en objetos. Principios clave: - encapsulaci贸n; - herencia; - polimorfismo; - abstracci贸n. En Python, la POO suele combinarse con composici贸n y tipado por comportamiento. **En resumen:** - La POO estructura el dominio mediante clases y objetos. - Python soporta la POO de forma flexible, sin demasiado c贸digo ceremonial. - En la pr谩ctica, la composici贸n suele ser mejor que una herencia profunda.
109. 驴Qu茅 es una `class` en Python? #### Python Una `class` es una plantilla para crear objetos con atributos y m茅todos. ```python class User: def __init__(self, name: str) -> None: self.name = name ``` La clase define la estructura y el comportamiento de futuras instancias. **En resumen:** - Una clase describe los datos y las operaciones sobre ellos. - A partir de una clase se crean objetos (instancias). - Es la unidad b谩sica de modelado en POO.
110. 驴C贸mo se crea un objeto en Python? #### Python Un objeto se crea llamando a la clase: ```python class User: def __init__(self, name: str) -> None: self.name = name user = User("Ada") ``` Durante la creaci贸n, se ejecuta `__init__` para inicializar el estado. **En resumen:** - Objeto = instancia de una clase. - Creaci贸n: `instancia = ClassName(...)`. - `__init__` configura los atributos iniciales.
111. 驴Qu茅 son los objetos y los atributos? #### Python Un objeto es una instancia concreta de un tipo o clase. Un atributo es un par nombre-valor asociado al objeto (dato o m茅todo). ```python user.name # atributo de datos user.save() # atributo m茅todo ``` **En resumen:** - Un objeto almacena estado y comportamiento. - Los atributos describen ese estado y comportamiento. - El acceso a los atributos se hace con notaci贸n de punto.
112. 驴Qu茅 papel cumple el m茅todo `__init__()` en una clase? #### Python `__init__` es el inicializador de la instancia: se llama despu茅s de crear el objeto y rellena su estado inicial. ```python class Account: def __init__(self, owner: str, balance: float = 0.0) -> None: self.owner = owner self.balance = balance ``` **En resumen:** - `__init__` define los atributos iniciales del objeto. - Funciona como punto de entrada para configurar la instancia. - No crea el objeto, solo lo inicializa.
113. 驴Para qu茅 sirve el par谩metro `self` en los m茅todos de clase de Python? #### Python `self` es una referencia a la instancia actual. A trav茅s de 茅l, el m茅todo lee y modifica los atributos de la instancia. ```python def deposit(self, amount: float) -> None: self.balance += amount ``` El nombre `self` no est谩 reservado por la sintaxis, pero es el est谩ndar aceptado de forma general. **En resumen:** - `self` vincula el m茅todo con un objeto concreto. - A trav茅s de `self` se accede a los datos de la instancia. - Es el primer par谩metro obligatorio de un m茅todo de instancia.
114. 驴C贸mo se definen los m茅todos dentro de una clase? #### Python Los m茅todos se definen como funciones dentro de una `class`. ```python class Calculator: def add(self, a: int, b: int) -> int: return a + b ``` Tipos habituales: de instancia (`self`), de clase (`@classmethod`, `cls`) y est谩tico (`@staticmethod`, sin `self/cls`). **En resumen:** - Un m茅todo es una funci贸n dentro del cuerpo de una clase. - El tipo de m茅todo lo determinan el decorador y la firma. - El m谩s com煤n es el m茅todo de instancia.
115. Explique el concepto de "todo es un objeto" en Python y d茅 ejemplos. #### Python En Python, casi todo es un objeto: n煤meros, strings, funciones, clases y m贸dulos. Por eso, todo tiene tipo, atributos y comportamiento. ```python type(10) # <class 'int'> type(len) # <class 'builtin_function_or_method'> type(str) # <class 'type'> ``` **En resumen:** - Un modelo de objetos unificado simplifica el lenguaje. - Las funciones y las clases tambi茅n son objetos de primera clase. - Esto hace que Python sea flexible para metaprogramaci贸n.
116. D茅 un ejemplo de una clase con m茅todos que realicen c谩lculos basados en atributos. #### Python ```python class Rectangle: def __init__(self, width: float, height: float) -> None: self.width = width self.height = height def area(self) -> float: return self.width * self.height def perimeter(self) -> float: return 2 * (self.width + self.height) ``` **En resumen:** - Los m茅todos pueden calcular valores a partir de los atributos de la instancia. - Esto encapsula la l贸gica de dominio dentro del objeto. - La API de la clase se vuelve m谩s autodocumentada.
117. Describa una situaci贸n en la que pueda ser necesario usar varias clases en un programa de Python. #### Python Cuando el dominio tiene varias responsabilidades, se reparten entre distintas clases. Por ejemplo, en e-commerce: `Order`, `OrderItem`, `PaymentService`, `InventoryService`. Esto aporta: - una separaci贸n clara de responsabilidades; - menor acoplamiento; - sustituci贸n y pruebas de componentes m谩s simples. **En resumen:** - Varias clases hacen falta para modelar un dominio complejo. - Separar responsabilidades mejora el mantenimiento. - La composici贸n de clases suele ser mejor que un "god object".
118. 驴Cu谩l es la diferencia entre m茅todo de instancia, m茅todo de clase y m茅todo est谩tico? #### Python - M茅todo de instancia: tiene `self` y trabaja con una instancia concreta. - M茅todo de clase: tiene `cls` y trabaja con la clase en general. - M茅todo est谩tico: no tiene `self/cls`; es una funci贸n utilitaria dentro del espacio de nombres de la clase. **En resumen:** - Instancia -> l贸gica de la instancia. - Clase -> l贸gica de la clase o constructores alternativos. - Static -> l贸gica auxiliar sin acceso al estado.
119. 驴Qu茅 es `@classmethod` en Python y en qu茅 se diferencia de los m茅todos normales? #### Python `@classmethod` pasa la clase (`cls`) como primer argumento, no la instancia. A menudo se usa para m茅todos factor铆a. ```python class User: def __init__(self, name: str) -> None: self.name = name @classmethod def from_email(cls, email: str) -> User: return cls(email.split("@")[0]) ``` **En resumen:** - `classmethod` trabaja a nivel de clase. - Es c贸modo para constructores alternativos. - No requiere una instancia ya creada.
120. 驴Qu茅 es `@staticmethod` en las clases de Python y cu谩ndo conviene usarlo? #### Python `@staticmethod` define un m茅todo sin `self` ni `cls` autom谩ticos. Pertenece l贸gicamente a la clase, pero no depende de su estado. ```python class Math: @staticmethod def clamp(value: int, min_v: int, max_v: int) -> int: return max(min_v, min(value, max_v)) ``` **En resumen:** - `staticmethod` es una funci贸n dentro del espacio de nombres de la clase. - 脷salo para l贸gica auxiliar sin acceso a atributos. - No sirve si necesitas estado de instancia o de clase.
121. 驴Cu谩l es la diferencia entre `@classmethod` y `@staticmethod` en las clases de Python? #### Python La diferencia est谩 en el primer argumento y en el nivel de acceso: - `@classmethod` recibe `cls` y puede trabajar con el estado de la clase; - `@staticmethod` no recibe nada autom谩ticamente. `classmethod` se usa m谩s a menudo para factor铆as o constructores polim贸rficos, y `staticmethod` para utilidades. **En resumen:** - `classmethod` conoce la clase. - `staticmethod` est谩 aislado del estado de clase y de instancia. - La elecci贸n depende de si necesitas acceso a `cls`.
122. 驴Qu茅 son los atributos de instancia en las clases de Python y en qu茅 se diferencian de los atributos de clase? #### Python Los atributos de instancia pertenecen a un objeto concreto (`self.x`). Los atributos de clase pertenecen a la clase y se comparten entre todas las instancias. ```python class User: role = "member" # atributo de clase def __init__(self, name: str) -> None: self.name = name # atributo de instancia ``` **En resumen:** - Los atributos de instancia almacenan estado individual. - Los atributos de clase almacenan configuraci贸n compartida. - Las mutaciones de atributos de clase afectan a todas las instancias.
123. 驴Qu茅 es `__slots__` en Python? #### Python `__slots__` limita el conjunto de atributos permitidos en una clase y puede reducir el consumo de memoria al eliminar `__dict__` en las instancias. ```python class Point: __slots__ = ("x", "y") def __init__(self, x: int, y: int) -> None: self.x = x self.y = y ``` **Matices de uso:** - **Ahorro de memoria:** los objetos ocupan bastante menos espacio, porque los atributos se almacenan en un array fijo y no en la tabla hash `__dict__`. - **Velocidad:** el acceso a atributos con `__slots__` suele ser un poco m谩s r谩pido. - **Ausencia de `__dict__`:** no podr谩s a帽adir din谩micamente nuevos atributos que no est茅n en la lista `__slots__` (a menos que a帽adas `"__dict__"` a la propia lista). - **Referencias d茅biles:** si quieres usar `weakref`, debes a帽adir expl铆citamente `"__weakref__"` a `__slots__`. **En resumen:** - `__slots__` es 煤til para millones de objetos ligeros, por ejemplo nodos de un grafo. - Elimina `__dict__` y `__weakref__` por defecto. - Reduce flexibilidad a cambio de rendimiento y control.
124. 驴Qu茅 son los magic methods (m茅todos dunder) en las clases de Python y por qu茅 se llaman "m谩gicos"? #### Python Los m茅todos dunder (`__init__`, `__str__`, `__len__`, `__eq__`, ...) son puntos de enganche especiales que Python llama autom谩ticamente en respuesta a operadores y funciones integradas. Se llaman "m谩gicos" porque integran tu clase en el comportamiento del lenguaje. **En resumen:** - Los m茅todos dunder definen el comportamiento protocolario del objeto. - Permiten que tus clases se comporten "como tipos integrados". - 脷salos solo cuando haya una necesidad sem谩ntica clara.
125. 驴Para qu茅 sirve el m茅todo `__del__`? #### Python `__del__` es un finalizador que puede llamarse antes de que el GC destruya el objeto. Su comportamiento no es determinista, as铆 que para gestionar recursos es mejor usar gestores de contexto (`with`) y cierre expl铆cito. **En resumen:** - `__del__` no garantiza una ejecuci贸n oportuna. - No apoyes una limpieza cr铆tica solo en 茅l. - El enfoque recomendado es `with` o `try-finally`.
126. D茅 un ejemplo de uso del m茅todo m谩gico `__str__` para definir la representaci贸n textual de una clase propia en Python. #### Python ```python class User: def __init__(self, name: str, active: bool) -> None: self.name = name self.active = active def __str__(self) -> str: status = "active" if self.active else "inactive" return f"User(name={self.name}, status={status})" ``` `str(user)` y `print(user)` usar谩n `__str__`. **En resumen:** - `__str__` da una representaci贸n comprensible para humanos del objeto. - Es 煤til para logs y salida en CLI. - Debe ser corto y legible.
127. 驴Para qu茅 se usan `__str__` y `__repr__`? #### Python `__str__` est谩 orientado al lector final. `__repr__` est谩 orientado al desarrollador y a la depuraci贸n, y es deseable que sea inequ铆voco. `print(obj)` usa principalmente `__str__`, mientras que REPL y `repr(obj)` usan `__repr__`. **En resumen:** - `__str__` sirve para una salida amigable. - `__repr__` sirve para una representaci贸n t茅cnica. - Es buena pr谩ctica tener ambos si la clase es de dominio.
128. 驴C贸mo funciona la sobrecarga de operadores en Python y por qu茅 es 煤til? #### Python La sobrecarga de operadores es la implementaci贸n de m茅todos dunder de operadores (`__add__`, `__sub__`, `__eq__`, ...) para que los objetos de tu propia clase soporten operadores. ```python class Vector2: def __init__(self, x: float, y: float) -> None: self.x = x self.y = y def __add__(self, other: "Vector2") -> "Vector2": return Vector2(self.x + other.x, self.y + other.y) ``` **En resumen:** - Da una sintaxis natural para tipos de dominio. - Mejora la expresividad de la API. - Es importante mantener una sem谩ntica matem谩ticamente esperable.
129. 驴Qu茅 es la herencia? #### Python La herencia permite crear una clase hija que hereda atributos y m茅todos de una clase base y puede ampliar o sobrescribir su comportamiento. **En resumen:** - La herencia favorece la reutilizaci贸n de c贸digo. - La clase hija puede sobrescribir m茅todos de la clase base. - Una jerarqu铆a excesiva complica el mantenimiento, por eso la composici贸n suele ser mejor.
130. 驴Qu茅 es la herencia simple en Python? #### Python La herencia simple significa que una clase tiene solo un padre directo. ```python class Animal: ... class Dog(Animal): ... ``` Esta es la forma m谩s simple y normalmente la m谩s legible de herencia. **En resumen:** - Una clase hija -> una clase base. - Modelo de resoluci贸n de m茅todos simple. - Suele ser suficiente para la mayor铆a de modelos de negocio.
131. 驴C贸mo se implementa la herencia en las clases de Python y qu茅 sintaxis se usa para ello? #### Python La sintaxis es `class Child(Base):`. ```python class Base: def greet(self) -> str: return "hello" class Child(Base): def greet(self) -> str: return "hi" ``` Si necesitas llamar a la l贸gica base, usa `super()`. **En resumen:** - La herencia se define entre par茅ntesis despu茅s del nombre de la clase. - La clase hija recibe la API de la clase base. - La sobrescritura permite adaptar el comportamiento.
132. 驴C贸mo acceder a los miembros de la clase base desde una clase hija? #### Python El acceso es posible directamente a trav茅s de atributos y m茅todos heredados o mediante `super()`. ```python class Base: def greet(self) -> str: return "hello" class Child(Base): def greet(self) -> str: return super().greet() + " world" ``` **En resumen:** - Los miembros heredados est谩n disponibles autom谩ticamente en la clase hija. - `super()` llama correctamente a la l贸gica de la clase base. - Esto es importante para ampliar comportamiento, no para duplicarlo.
133. 驴Para qu茅 sirve la funci贸n `super()` en la herencia de Python y c贸mo se usa? #### Python `super()` devuelve un proxy a la siguiente clase seg煤n el MRO para llamar a sus m茅todos. Se usa t铆picamente en `__init__` y en herencia m煤ltiple cooperativa. ```python class Child(Base): def __init__(self, value: int) -> None: super().__init__() self.value = value ``` **En resumen:** - `super()` llama a la implementaci贸n padre sin fijar el nombre de la clase. - Ayuda a mantener la correcci贸n del MRO. - Es la forma recomendada de trabajar con herencia.
134. Describa la funci贸n `isinstance()` en Python y d茅 un ejemplo de uso. #### Python `isinstance(obj, cls_or_tuple)` comprueba si un objeto pertenece a un tipo o a su subclase. ```python isinstance(10, int) # True isinstance(True, int) # True isinstance("x", (str, bytes)) # True ``` **En resumen:** - `isinstance` es m谩s seguro que `type(obj) is ...` en c贸digo polim贸rfico. - Tiene en cuenta la jerarqu铆a de herencia. - Soporta tuplas de tipos.
135. Explique la funci贸n `issubclass()` en Python y d茅 un ejemplo de uso. #### Python `issubclass(Sub, Base)` comprueba si la clase `Sub` es subclase de `Base`. ```python class Animal: ... class Dog(Animal): ... issubclass(Dog, Animal) # True ``` **En resumen:** - Trabaja con clases, no con instancias. - Es 煤til para validar APIs a nivel de tipos. - Tiene en cuenta la herencia transitiva.
136. 驴Qu茅 es la herencia m煤ltiple? #### Python La herencia m煤ltiple es la herencia de una clase a partir de varias clases base. ```python class A: ... class B: ... class C(A, B): ... ``` Da flexibilidad, pero exige disciplina en el dise帽o de m茅todos y en `super()`. **En resumen:** - Una clase puede heredar comportamiento de varias fuentes. - Es 煤til para el enfoque basado en mixins. - Puede hacer m谩s dif铆cil entender el MRO.
137. 驴C贸mo funciona el MRO (Method Resolution Order) en la herencia m煤ltiple? #### Python El MRO define el orden de b煤squeda de m茅todos en la jerarqu铆a de clases. En Python se usa el algoritmo de linealizaci贸n C3. **Diamond Problem (problema del diamante):** es el caso cl谩sico en el que la clase `D` hereda de `B` y `C`, y ambas heredan de `A`. El MRO garantiza que `A` se revisar谩 solo despu茅s de que se hayan revisado todos sus descendientes (`B` y `C`). ```python class A: pass class B(A): pass class C(A): pass class D(B, C): pass print(D.mro()) # [D, B, C, A, object] ``` El orden puede verse mediante `ClassName.__mro__` o `ClassName.mro()`. **En resumen:** - El MRO decide de qu茅 clase base tomar un m茅todo. - El orden es predecible y est谩 definido formalmente (C3). - Gracias al MRO, Python maneja correctamente el problema del diamante. - Para la herencia cooperativa, todas las clases deben llamar a `super()`.
138. 驴Cu谩les son las ventajas y desventajas de usar herencia m煤ltiple? #### Python Ventajas: - reutilizaci贸n de comportamiento desde varias fuentes; - mixins c贸modos para "a帽adir" capacidades. Desventajas: - MRO m谩s complejo; - riesgo de conflictos de nombres o comportamiento; - depuraci贸n e incorporaci贸n m谩s dif铆ciles. **En resumen:** - La herencia m煤ltiple es potente, pero exige reglas de dise帽o estrictas. - Para la mayor铆a de casos, la composici贸n es m谩s simple. - Usa herencia m煤ltiple sobre todo para mixins peque帽os.
139. 驴Qu茅 son los mixins? #### Python Un mixin es una clase peque帽a con comportamiento adicional y espec铆fico, pensada para combinarse mediante herencia y no para usarse por s铆 sola. Ejemplos: `TimestampMixin`, `JsonSerializableMixin`. **En resumen:** - Un mixin a帽ade una capacidad concreta. - Normalmente no tiene su propio ciclo de vida completo. - Encaja bien con la herencia m煤ltiple.
140. 驴Qu茅 es la encapsulaci贸n en Python? #### Python La encapsulaci贸n es ocultar la implementaci贸n interna detr谩s de una API p煤blica estable. En Python se implementa principalmente con convenciones y `property`, no con modificadores de acceso r铆gidos. **En resumen:** - El c贸digo cliente trabaja con la interfaz, no con los detalles. - La encapsulaci贸n reduce el acoplamiento entre componentes. - Facilita cambiar la implementaci贸n interna sin romper la API.
141. 驴Cu谩l es la diferencia entre acceso p煤blico, privado y protegido? #### Python En Python esto son principalmente convenciones de nombres: - `public`: `name` -> accesible en todas partes; - `protected`: `_name` -> uso interno por convenci贸n; - `private`: `__name` -> cambio interno de nombre (`_ClassName__name`), no protecci贸n absoluta. **En resumen:** - Python no tiene modificadores de acceso estrictos como Java o C#. - `_name` y `__name` son se帽ales de intenci贸n para desarrolladores. - El control real de acceso se construye mediante dise帽o de API.
142. 驴Qu茅 es el polimorfismo y c贸mo se implementa en Python? #### Python El polimorfismo es la posibilidad de trabajar con distintos objetos a trav茅s de una interfaz com煤n. En Python suele implementarse con duck typing y protocolos. ```python def render(obj) -> str: return obj.to_text() ``` Cualquier objeto con un m茅todo `to_text` sirve. **En resumen:** - Una interfaz, muchas implementaciones. - En Python, el polimorfismo suele ser conductual, no jer谩rquico. - Esto simplifica ampliar el sistema con nuevos tipos.
143. 驴Qu茅 es la abstracci贸n en Python? #### Python La abstracci贸n consiste en destacar la API esencial y ocultar detalles innecesarios de implementaci贸n. El cliente trabaja con el contrato, no con los pasos internos. **En resumen:** - La abstracci贸n reduce la carga cognitiva. - Facilita sustituir la implementaci贸n sin cambiar el c贸digo cliente. - Se implementa mediante interfaces, ABC, protocolos y fachadas.
144. 驴C贸mo implementar abstracci贸n de datos? #### Python Enfoque: - ocultar el acceso directo a campos internos (`_field`); - ofrecer una API controlada mediante m茅todos o `@property`; - validar invariantes en la l贸gica del setter. ```python class Temperature: def __init__(self, celsius: float) -> None: self.celsius = celsius @property def celsius(self) -> float: return self._celsius @celsius.setter def celsius(self, value: float) -> None: if value < -273.15: raise ValueError("invalid temperature") self._celsius = value ``` **En resumen:** - La abstracci贸n de datos protege los invariantes del objeto. - `property` da acceso controlado al estado. - Los detalles internos pueden cambiarse sin cambiar la API.
145. 驴Qu茅 son ABC y `@abstractmethod`? #### Python ABC (Abstract Base Class) es una clase base abstracta del m贸dulo `abc`. `@abstractmethod` marca un m茅todo que la subclase debe implementar obligatoriamente. ```python from abc import ABC, abstractmethod class Storage(ABC): @abstractmethod def save(self, data: bytes) -> None: ... ``` **En resumen:** - ABC formaliza el contrato de la jerarqu铆a. - `@abstractmethod` impide instanciar una implementaci贸n incompleta. - Es 煤til para arquitecturas extensibles o basadas en complementos.
146. 驴Qu茅 es property en Python y c贸mo se usa? #### Python `property` convierte m茅todos de acceso en una API similar a atributos, con posibilidad de validaci贸n, c谩lculos o l贸gica perezosa. ```python class User: def __init__(self, name: str) -> None: self._name = name @property def name(self) -> str: return self._name ``` **En resumen:** - `property` da control de acceso sin cambiar la sintaxis externa. - Sirve para validaci贸n y valores derivados. - Permite evolucionar la API sin romper a los clientes.
147. 驴Qu茅 es `@property`? #### Python `@property` es un decorador para un m茅todo getter. Junto con `@x.setter` y `@x.deleter`, forma un atributo gestionado. **En resumen:** - `@property` permite leer un m茅todo como si fuera un campo. - Ayuda a encapsular la implementaci贸n interna. - A menudo se usa para APIs retrocompatibles.
148. 驴Qu茅 es un descriptor en Python? #### Python Un descriptor es un objeto que implementa `__get__`, `__set__` o `__delete__` y controla el acceso a atributos de otra clase. A trav茅s de descriptores funcionan `property`, `classmethod` y `staticmethod`. **En resumen:** - Un descriptor es un mecanismo de bajo nivel para acceso a atributos. - Permite reutilizar l贸gica de validaci贸n o proxy de campos. - Es la base de muchas t茅cnicas de metaprogramaci贸n en Python.
149. 驴Cu谩l es la diferencia entre property y descriptor? #### Python `property` es un descriptor de alto nivel ya preparado para un atributo. Un descriptor personalizado es un mecanismo m谩s general que puede reutilizarse en muchos campos o clases. **En resumen:** - `property` es m谩s simple y local. - Un descriptor es m谩s flexible y escalable. - `property` est谩 construido sobre el protocolo descriptor.
150. 驴Cu谩ndo conviene usar property y cu谩ndo un descriptor? #### Python Usa `property` cuando la l贸gica afecta a uno o dos campos de una clase concreta. Usa un descriptor cuando la misma l贸gica (validaci贸n, casting, inicializaci贸n perezosa) debe reutilizarse en muchas clases. **En resumen:** - L贸gica local de un campo -> `property`. - Reutilizaci贸n de la pol铆tica de acceso -> descriptor. - Un descriptor es ventajoso en modelos de dominio grandes.
151. 驴Para qu茅 se usan `setattr()`, `getattr()` y `hasattr()`? 驴Cu谩l es la diferencia entre ellos? #### Python Son funciones de acceso din谩mico a atributos: - `getattr(obj, name[, default])` -> leer un atributo; - `setattr(obj, name, value)` -> establecer un atributo; - `hasattr(obj, name)` -> comprobar si existe. ```python value = getattr(user, "email", None) if not hasattr(user, "active"): setattr(user, "active", True) ``` **En resumen:** - `getattr/setattr/hasattr` sirven para trabajar din谩micamente con objetos. - Son 煤tiles en c贸digo gen茅rico, serializaci贸n y adaptadores. - Es importante no abusar de ellas para no perder legibilidad.
152. Explique el significado del m茅todo `__set_name__` en los descriptores de Python y d茅 un ejemplo de uso. #### Python `__set_name__(self, owner, name)` se llama durante la creaci贸n de la clase y permite que el descriptor conozca el nombre del atributo al que est谩 vinculado. ```python class Field: def __set_name__(self, owner, name): self.name = name ``` **En resumen:** - `__set_name__` inicializa el descriptor con el contexto de la clase. - Permite crear validadores de campos reutilizables. - Se ejecuta una sola vez en la etapa de creaci贸n de la clase.
153. 驴Qu茅 es `dataclass` y cu谩ndo conviene usarlo? #### Python `@dataclass` genera autom谩ticamente c贸digo repetitivo (`__init__`, `__repr__`, `__eq__`). Es adecuado para modelos de datos sin comportamiento complejo. ```python from dataclasses import dataclass @dataclass(slots=True) class User: name: str active: bool = True ``` **En resumen:** - `dataclass` reduce c贸digo en modelos de datos. - Es una buena opci贸n para DTO y configuraciones. - Para validaci贸n compleja, a menudo hacen falta otras herramientas.
154. 驴Cu谩l es la diferencia entre `dataclass` y Pydantic? #### Python `dataclass` se centra en describir la estructura de forma c贸moda. Pydantic a帽ade validaci贸n en tiempo de ejecuci贸n, an谩lisis y serializaci贸n de datos. **En resumen:** - `dataclass` es m谩s ligero y r谩pido para modelos internos. - Pydantic es mejor para entrada externa y APIs. - La elecci贸n depende de la necesidad de validaci贸n en ejecuci贸n.
155. 驴Qu茅 son las anotaciones de tipos y para qu茅 sirven? #### Python Las anotaciones de tipos son anotaciones en firmas y variables que forman un contrato expl铆cito. Mejoran las sugerencias del IDE y el an谩lisis est谩tico. **En resumen:** - Las anotaciones de tipos aumentan la claridad de la API. - Permiten detectar antes cierta clase de errores. - Son 煤tiles incluso en un lenguaje din谩mico.
156. 驴C贸mo funciona la comprobaci贸n est谩tica de tipos (`mypy`)? #### Python `mypy` lee anotaciones de tipos y analiza el c贸digo sin ejecutarlo, comprobando la compatibilidad de tipos. Detecta errores de integraci贸n antes de la ejecuci贸n. **En resumen:** - `mypy` realiza una comprobaci贸n parecida al tiempo de compilaci贸n para Python. - Funciona mejor en CI. - Los modos estrictos reducen la cantidad de bugs en producci贸n.
157. 驴C贸mo garantizar seguridad de tipos en un proyecto Python? #### Python - a帽adir anotaciones de tipos de forma consistente en la API p煤blica; - activar `mypy`/`pyright` en CI; - usar `TypedDict`, `Protocol` y gen茅ricos; - minimizar `Any` y los castings impl铆citos. **En resumen:** - La seguridad de tipos es un proceso, no una acci贸n puntual. - El mayor efecto lo da una puerta de CI para tipos. - Aumentar el rigor de forma gradual funciona mejor que un "big bang".
158. 驴Qu茅 es `TypedDict`? #### Python `TypedDict` describe una forma tipada de diccionario: qu茅 claves se esperan y de qu茅 tipo son sus valores. ```python from typing import TypedDict class UserPayload(TypedDict): name: str; active: bool ``` **En resumen:** - `TypedDict` tipa un `dict` con claves fijas. - Es c贸modo para estructuras parecidas a JSON. - Lo comprueba un analizador est谩tico.
159. 驴Qu茅 es `Protocol` en typing? #### Python `Protocol` describe un contrato conductual (tipado estructural): un tipo es compatible si tiene los m茅todos o atributos necesarios, independientemente de la herencia. **En resumen:** - `Protocol` implementa duck typing en el tipado est谩tico. - Reduce el acoplamiento r铆gido a clases concretas. - Es 煤til para APIs testeables y extensibles.
160. 驴Qu茅 son los gen茅ricos en Python? #### Python Los gen茅ricos permiten escribir tipos y funciones parametrizados por otros tipos. En la sintaxis moderna: `class Box[T]: ...`, `def first[T](...) -> T`. **En resumen:** - Los gen茅ricos hacen que los tipos sean reutilizables. - Refuerzan la seguridad de tipos de colecciones y contenedores. - Reducen la duplicaci贸n de c贸digo tipado.
161. 驴Qu茅 es Pydantic y para qu茅 se usa? #### Python Pydantic es una biblioteca para describir esquemas de datos con validaci贸n en tiempo de ejecuci贸n, conversi贸n de tipos y serializaci贸n c贸moda. Casos t铆picos: modelos de solicitud y respuesta de FastAPI y configuraci贸n de la aplicaci贸n. **En resumen:** - Pydantic valida datos externos durante la ejecuci贸n. - Es c贸modo para APIs e integraciones. - Proporciona errores de validaci贸n claros y esquemas.
162. 驴Qu茅 son las exceptions en Python? #### Python Una exception es un objeto que se帽ala una situaci贸n err贸nea o excepcional durante la ejecuci贸n del c贸digo. **En resumen:** - Las exceptions interrumpen el flujo normal. - Deben manejarse donde se pueda tomar una decisi贸n. - Un modelo correcto de errores aumenta la fiabilidad del sistema.
163. 驴Cu谩les son los tres tipos de errores en Python y en qu茅 se diferencian? #### Python - Syntax errors: errores de sintaxis antes de la ejecuci贸n; - Excepciones en tiempo de ejecuci贸n: errores durante la ejecuci贸n; - Logical errors: el c贸digo se ejecuta, pero el resultado es incorrecto. **En resumen:** - Los errores de sintaxis y de ejecuci贸n los detecta el int茅rprete. - Los errores l贸gicos se detectan con pruebas y revisi贸n. - Cada tipo requiere un enfoque de diagn贸stico distinto.
164. 驴C贸mo usar `try`, `except`, `else` y `finally`? #### Python `try` contiene una operaci贸n de riesgo, `except` maneja el error, `else` se ejecuta cuando no hubo error y `finally` se ejecuta siempre (limpieza). ```python try: data = load() except FileNotFoundError: data = {} else: validate(data) finally: close_connections() ``` **En resumen:** - Usa `else` para el c贸digo de la ruta exitosa. - Usa `finally` para recursos y limpieza. - Captura exceptions concretas, no "todo".
165. 驴Qu茅 significa el orden de las categor铆as `except`? #### Python Los `except` se comprueban de arriba abajo, as铆 que primero se colocan las exceptions m谩s concretas y las generales (`Exception`) al final. **En resumen:** - El orden de `except` influye en qu茅 manejador se ejecutar谩. - Un `except` amplio arriba "se come" los casos espec铆ficos. - Esto es cr铆tico para un flujo de recuperaci贸n correcto.
166. 驴Cu谩l es el prop贸sito de la palabra clave `assert` en c贸digo Python? #### Python `assert` comprueba un invariante y lanza `AssertionError` si la condici贸n es falsa. Sirve para comprobaciones internas del desarrollador, no para validar entrada de usuario. **En resumen:** - `assert` documenta "esto debe ser verdadero". - No sustituye el manejo de errores en producci贸n. - 脷salo para contratos en la l贸gica interna.
167. 驴En qu茅 se diferencia `raise` de simplemente imprimir un mensaje de error en Python? #### Python `raise` cambia el flujo de control y se帽ala el error al llamador. `print` solo muestra texto y no detiene el escenario err贸neo. **En resumen:** - `raise` es un mecanismo de manejo de errores; `print`, no. - Las exceptions pueden capturarse y registrarse de forma centralizada. - `print` sirve para diagn贸stico, no para contratos de error.
168. 驴C贸mo crear una excepci贸n propia? #### Python Crea una clase que herede de `Exception` (o de una excepci贸n base m谩s espec铆fica). ```python class InvalidOrderError(Exception): pass ``` **En resumen:** - Una excepci贸n propia hace que los errores sean expresivos para el dominio. - Permite capturar con precisi贸n los casos necesarios. - Es mejor que usar `ValueError` para todo.
169. 驴Qu茅 valor tiene crear excepciones propias en Python y c贸mo mejoran el manejo de errores? #### Python Las exceptions propias forman un modelo de errores expl铆cito del dominio y separan los fallos t茅cnicos de las reglas de negocio. **En resumen:** - Mejoran la legibilidad y el mantenimiento de los manejadores. - Aportan una sem谩ntica m谩s precisa en logs y APIs. - Simplifican las pruebas de escenarios negativos.
170. 驴C贸mo est谩n organizadas las excepciones en Python y cu谩l es la jerarqu铆a de sus clases? #### Python La jerarqu铆a parte de `BaseException`. En c贸digo de aplicaci贸n casi siempre se trabaja con descendientes de `Exception`. Ramas principales: `ValueError`, `TypeError`, `KeyError`, `OSError`, `RuntimeError`. **En resumen:** - Las excepciones forman un 谩rbol de clases. - Es mejor capturar subclases concretas. - `BaseException` normalmente no se captura en la l贸gica de negocio.
171. 驴Qu茅 enfoques hay para manejar varias excepciones distintas en Python y por qu茅 conviene tratarlas por separado? #### Python Enfoques: - `except` separados para cada tipo; - agrupaci贸n de casos l贸gicamente equivalentes: `except (A, B):`; - estrategias de recuperaci贸n distintas para cada categor铆a. **En resumen:** - Distintas excepciones suelen requerir acciones diferentes. - El manejo separado reduce defectos ocultos. - Los logs se vuelven m谩s precisos y 煤tiles.
172. 驴Para qu茅 sirve relanzar una excepci贸n en Python y cu谩ndo es 煤til? #### Python Relanzar (`raise` sin argumentos dentro de `except`) permite a帽adir contexto (logs, m茅tricas, limpieza) y propagar el mismo error hacia arriba. **En resumen:** - El relanzamiento conserva el traceback original. - Es 煤til para un manejo centralizado en niveles superiores. - No "tragues" errores cr铆ticos sin necesidad.
173. 驴Por qu茅 conviene limitar el uso de bloques try-except en programas Python y c贸mo afecta eso al rendimiento? #### Python `try/except` es necesario, pero no deber铆a envolver bloques grandes "por si acaso". Es especialmente costoso cuando las excepciones ocurren con frecuencia (flujo guiado por excepciones). **En resumen:** - Captura solo errores esperados en un punto estrecho. - Las excepciones frecuentes empeoran el rendimiento y la legibilidad. - Prefiere comprobaciones expl铆citas cuando sea adecuado.
174. 驴C贸mo manejar errores al trabajar con archivos? #### Python Usa `with` y captura excepciones concretas (`FileNotFoundError`, `PermissionError`, `UnicodeDecodeError`, `OSError`). ```python try: with open(path, "r", encoding="utf-8") as f: content = f.read() except FileNotFoundError: ... ``` **En resumen:** - `with` garantiza el cierre del archivo. - Maneja errores concretos de entrada y salida. - Registra el contexto: ruta, modo y codificaci贸n.
175. 驴Qu茅 modos de trabajo con archivos existen en Python? #### Python Modos principales: - `r` lectura; - `w` sobrescritura; - `a` anexar al final; - `x` creaci贸n de un archivo nuevo; - `b` modo binario; - `t` modo texto (por defecto); - `+` lectura y escritura. **En resumen:** - El modo define la sem谩ntica de seguridad y cambio del archivo. - `w` borra el contenido; `a` conserva lo existente. - Para datos binarios, usa `b`.
176. 驴Por qu茅 es importante cerrar archivos despu茅s de las operaciones y qu茅 puede pasar si se dejan abiertos? #### Python Un archivo abierto mantiene un descriptor del sistema operativo. Si no se cierra: - fuga de descriptores de archivo; - bloqueos de archivos o vaciado incompleto del b煤fer; - inestabilidad en procesos largos. **En resumen:** - Cerrar un archivo libera recursos del sistema operativo. - `with` automatiza un cierre seguro. - Esto es cr铆tico para servicios y scripts por lotes.
177. 驴Cu谩l es la diferencia entre `read()`, `readline()` y `readlines()` al leer archivos? #### Python - `read()` lee todo el archivo, o `n` bytes o caracteres; - `readline()` lee una sola l铆nea; - `readlines()` lee todas las l铆neas en una lista. **En resumen:** - `read()` y `readlines()` pueden ser pesados en memoria. - Para archivos grandes, es mejor iterar con `for line in file`. - La elecci贸n depende del volumen y del escenario de procesamiento.
178. 驴C贸mo escribir datos en un archivo en Python y cu谩l es la diferencia entre `w` (escritura) y `a` (anexar)? #### Python Escritura: ```python with open("out.txt", "w", encoding="utf-8") as f: f.write("hello\n") ``` `w` sobrescribe el archivo desde el principio; `a` a帽ade contenido nuevo al final. **En resumen:** - `w` borra los datos antiguos. - `a` conserva el contenido existente. - Para registros, normalmente se usa `a`.
179. 驴C贸mo trabajar de forma eficiente con archivos grandes? #### Python - leer en flujo, por l铆neas o por bloques; - evitar cargar todo el archivo en memoria; - usar b煤feres y generadores; - para datos columnares o tabulares, elegir formatos y analizadores adecuados. **En resumen:** - La clave es la lectura en flujo en lugar de la lectura completa. - Los generadores reducen el consumo de memoria. - El algoritmo de procesamiento importa m谩s que las microoptimizaciones.
180. 驴Qu茅 son los gestores de contexto? #### Python Un gestor de contexto administra un recurso mediante el protocolo `__enter__/__exit__`: apertura o inicializaci贸n y finalizaci贸n o limpieza garantizada. **En resumen:** - Proporciona un ciclo de vida seguro del recurso. - Funciona mediante `with`. - Reduce la cantidad de fugas de recursos.
181. 驴C贸mo funciona la construcci贸n `with`? #### Python `with` llama a `__enter__` al entrar en el bloque y a `__exit__` al salir, incluso si ocurre un error. ```python with open("data.txt", "r", encoding="utf-8") as f: data = f.read() ``` **En resumen:** - `with` garantiza la limpieza. - Hace que el trabajo con recursos sea declarativo. - Se recomienda para archivos, bloqueos, transacciones y sesiones.
182. 驴C贸mo crear un gestor de contexto propio? #### Python Hay dos enfoques: - una clase con `__enter__` y `__exit__`; - una funci贸n con `contextlib.contextmanager`. ```python from contextlib import contextmanager @contextmanager def temp_flag(): yield ``` **En resumen:** - Una clase sirve para estado complejo. - `contextmanager` es c贸modo para escenarios cortos. - Ambos garantizan la limpieza.
183. 驴C贸mo gestiona Python la memoria? #### Python CPython usa conteo de referencias y un recolector c铆clico de basura. Adem谩s, tiene un asignador interno (`pymalloc`) para objetos peque帽os. **En resumen:** - El mecanismo b谩sico es el conteo de referencias. - El GC elimina referencias c铆clicas. - La memoria no siempre se libera de inmediato a nivel del sistema operativo.
184. 驴Qu茅 es el conteo de referencias en Python y por qu茅 es importante para la gesti贸n de memoria? #### Python Cada objeto tiene un contador de referencias. Cuando llega a cero, el objeto puede liberarse. Esto permite liberar r谩pidamente la mayor铆a de objetos de vida corta. **En resumen:** - El conteo de referencias da un ciclo de vida predecible a los objetos. - No resuelve por s铆 solo las referencias c铆clicas. - Junto con el GC, forma un modelo completo de gesti贸n de memoria.
185. 驴Qu茅 es la recolecci贸n de basura en Python? #### Python La recolecci贸n de basura en CPython encuentra y elimina ciclos inalcanzables de objetos que no pueden limpiarse solo con conteo de referencias. **En resumen:** - El GC complementa el conteo de referencias. - Es especialmente importante para grafos c铆clicos de referencias. - Puede controlarse mediante el m贸dulo `gc`.
186. 驴C贸mo obtener la direcci贸n de memoria de un objeto en Python? #### Python En CPython, `id(obj)` suele corresponder a la direcci贸n de memoria del objeto (como un entero). Es una herramienta de diagn贸stico, no un identificador externo estable. **En resumen:** - `id()` da la identidad del objeto. - En CPython suele ser la direcci贸n de memoria. - No lo uses en l贸gica de negocio.
187. 驴Para qu茅 sirve la funci贸n `getrefcount()` del m贸dulo `sys` y c贸mo funciona en Python? #### Python `sys.getrefcount(obj)` devuelve el contador actual de referencias de un objeto (en CPython). El valor suele ser 1 mayor por la referencia temporal del argumento. **En resumen:** - Es una herramienta de diagn贸stico del comportamiento de memoria. - Es 煤til para analizar fugas de referencias. - No debe usarse como base en l贸gica de aplicaci贸n.
188. Explique con ejemplos la diferencia entre objetos mutables e inmutables en relaci贸n con el conteo de referencias y la gesti贸n de memoria. #### Python Los objetos inmutables no cambian, as铆 que una "modificaci贸n" crea un objeto nuevo. Los objetos mutables cambian en el lugar, y todas las referencias ven el cambio. ```python a = "x"; b = a; a += "y" # nuevo objeto x = [1]; y = x; y.append(2) # cambio del mismo objeto ``` **En resumen:** - Los inmutables reducen efectos secundarios. - Los mutables son m谩s eficientes para modificaciones en el lugar. - La diferencia es cr铆tica para copiado y referencias compartidas.
189. 驴Cu谩l es la diferencia entre copia superficial y copia profunda en Python, y cu谩ndo conviene usar cada enfoque? #### Python La copia superficial copia solo el contenedor externo; los objetos anidados siguen siendo compartidos. La copia profunda copia recursivamente toda la estructura. ```python import copy copy.copy(obj) copy.deepcopy(obj) ``` **En resumen:** - La copia superficial es suficiente para estructuras "planas". - La copia profunda hace falta para trabajar de forma aislada con datos mutables anidados. - La copia profunda es m谩s costosa en tiempo y memoria.
190. 驴Qu茅 son los m贸dulos y paquetes en Python? #### Python Un m贸dulo es un archivo `.py` independiente con c贸digo. Un paquete es un directorio de m贸dulos (espacio de nombres) que organiza el c贸digo en bloques m谩s grandes. **En resumen:** - M贸dulo = unidad de c贸digo. - Paquete = estructura para escalar m贸dulos. - Dividir en m贸dulos y paquetes mejora el mantenimiento.
191. 驴C贸mo importar un m贸dulo en Python? #### Python Formas principales: - `import module`; - `import module as m`; - `from module import name`; - `from package import submodule`. **En resumen:** - La importaci贸n carga un m贸dulo y lo hace disponible en el espacio de nombres. - Un alias (`as`) mejora la legibilidad y evita conflictos. - Conviene preferir importaciones expl铆citas.
192. 驴Qu茅 tipos de imports existen? #### Python Tipos habituales: - absolutos; - relativos; - selectivos (`from x import y`); - con alias (`as`); - din谩micos (`importlib`). **En resumen:** - El tipo de importaci贸n influye en la legibilidad y el mantenimiento. - En producci贸n suelen usarse importaciones absolutas. - Las importaciones din谩micas se aplican de forma puntual.
193. 驴C贸mo funciona el sistema de importaciones? #### Python El int茅rprete busca el m贸dulo en `sys.path`, lo carga una vez y lo almacena en la cach茅 de `sys.modules`. Una importaci贸n repetida usa esa cach茅. **En resumen:** - Importar = b煤squeda + ejecuci贸n del m贸dulo + almacenamiento en cach茅. - Esto explica por qu茅 el c贸digo del m贸dulo se ejecuta en la primera importaci贸n. - Las importaciones c铆clicas aparecen por el orden de inicializaci贸n de m贸dulos.
194. 驴Cu谩l es la diferencia entre importaci贸n absoluta y relativa? #### Python La importaci贸n absoluta empieza desde la ra铆z del paquete (`from app.utils import x`). La importaci贸n relativa usa puntos (`from .utils import x`). **En resumen:** - Las importaciones absolutas son m谩s legibles y estables. - Las relativas son c贸modas dentro del paquete, pero peores para refactorizar. - En proyectos grandes, conviene usar absolutas por defecto.
195. 驴Qu茅 hace la funci贸n `dir()` y c贸mo puede aplicarse a m贸dulos? #### Python `dir(obj)` devuelve una lista de atributos o nombres disponibles del objeto. Para m贸dulos, es una forma r谩pida de inspeccionar la API. ```python import math dir(math) ``` **En resumen:** - `dir()` ayuda en la exploraci贸n interactiva de m贸dulos. - Es 煤til en REPL y depuraci贸n. - No sustituye la documentaci贸n oficial.
196. Explique el papel de `if __name__ == "__main__":` en scripts de Python. #### Python Ese bloque se ejecuta solo cuando el archivo se lanza como script y no cuando se importa como m贸dulo. Esto separa el c贸digo reutilizable del punto de entrada de CLI. **En resumen:** - Permite tanto ejecutar el m贸dulo como importarlo. - Evita ejecuci贸n no deseada durante la importaci贸n. - Es el patr贸n est谩ndar para scripts.
197. 驴Qu茅 significa el archivo `__init__.py` en un paquete Python? #### Python `__init__.py` marca un directorio como paquete y puede inicializar la API a nivel de paquete, por ejemplo, reexportando clases o funciones. **En resumen:** - Define la interfaz p煤blica del paquete. - Puede contener una inicializaci贸n m铆nima. - No conviene sobrecargarlo con l贸gica pesada.
198. 驴Qu茅 buenas pr谩cticas existen para el estilo de importaciones en c贸digo Python? #### Python - agrupar importaciones: biblioteca est谩ndar, terceros y locales; - evitar `from x import *`; - mantener las importaciones al principio del archivo, salvo casos justificados de importaci贸n diferida; - usar ordenaci贸n y formateo (`ruff`, `isort`). **En resumen:** - Las importaciones consistentes mejoran la legibilidad. - Las importaciones expl铆citas reducen conflictos de nombres. - La automatizaci贸n con herramientas elimina errores manuales.
199. 驴Qu茅 m贸dulos integrados populares existen en Python? #### Python Ejemplos de m贸dulos populares de la biblioteca est谩ndar: - `os`, `sys`, `pathlib`, `json`, `datetime`, `re`, - `collections`, `itertools`, `functools`, `typing`, - `asyncio`, `subprocess`, `logging`, `argparse`. **En resumen:** - La biblioteca est谩ndar cubre la mayor铆a de tareas b谩sicas. - Esto reduce la cantidad de dependencias externas. - Conviene conocer bien la biblioteca est谩ndar antes de a帽adir paquetes de terceros.
200. 驴Qu茅 sabe sobre el paquete `collections` y qu茅 otros m贸dulos integrados se han usado? #### Python `collections` proporciona estructuras de alto nivel: - `Counter`, `defaultdict`, `deque`, `namedtuple`, `ChainMap`. Suele combinarse con: - `itertools` para pipelines iterativos; - `functools` para cach茅 y utilidades funcionales; - `pathlib`, `json`, `datetime` en tareas de aplicaci贸n. **En resumen:** - `collections` ampl铆a los contenedores b谩sicos con estructuras pr谩cticas. - A menudo mejora la simplicidad y el rendimiento del c贸digo. - Funciona bien junto con `itertools` y `functools`.
201. 驴Qu茅 devuelve `sys.argv`? #### Python `sys.argv` devuelve una lista de argumentos de la l铆nea de comandos: - `sys.argv[0]` -> nombre del script; - el resto de elementos -> argumentos pasados. **En resumen:** - `sys.argv` es la interfaz b谩sica de argumentos de l铆nea de comandos. - Los valores llegan como cadenas. - Para CLIs complejas, es mejor `argparse`.
202. 驴Cu谩l es el m贸dulo principal para trabajar con el sistema operativo en Python? #### Python El m贸dulo principal es `os` junto con `os.path`, y para una API moderna de rutas se recomienda `pathlib`. **En resumen:** - `os` da acceso a la API de procesos, entorno y sistema de archivos del SO. - `pathlib` es m谩s c贸modo para trabajar con rutas. - En proyectos reales, a menudo se usan ambos.
203. 驴C贸mo mezclar elementos de una lista usando el m贸dulo `random`? #### Python Usa `random.shuffle(list_)` para mezclar en el lugar. ```python import random items = [1, 2, 3, 4] random.shuffle(items) ``` **En resumen:** - `shuffle` modifica la lista original. - Funciona solo con secuencias mutables, por ejemplo listas. - Para una copia nueva: `random.sample(items, k=len(items))`.
204. 驴Qu茅 es un entorno virtual? #### Python Un entorno virtual es un entorno Python aislado con sus propios paquetes y versiones de dependencias para un proyecto concreto. **En resumen:** - El aislamiento elimina conflictos de dependencias entre proyectos. - La herramienta est谩ndar es `venv`. - Es una pr谩ctica b谩sica para un desarrollo reproducible.
205. 驴C贸mo funciona `pip`? #### Python `pip` instala, actualiza y elimina paquetes desde 铆ndices, normalmente PyPI, resuelve dependencias y los instala en el entorno actual. **En resumen:** - `pip` es el gestor de paquetes est谩ndar de Python. - Funciona dentro del int茅rprete o venv activo. - Para estabilidad, son importantes las versiones fijadas.
206. 驴Qu茅 es `requirements.txt`? #### Python `requirements.txt` es un archivo con la lista de dependencias, a menudo con versiones exactas, que se usa para una instalaci贸n reproducible. **En resumen:** - El formato es simple y compatible con `pip install -r`. - Lo mejor es fijar versiones exactas para producci贸n. - A menudo lo generan herramientas como `pip-tools` o `poetry export` a partir de listas declarativas o archivos de bloqueo.
207. 驴Qu茅 es `pyproject.toml` y por qu茅 se convirti贸 en est谩ndar? #### Python `pyproject.toml` es un archivo estandarizado de configuraci贸n del proyecto: metadatos del paquete, sistema de compilaci贸n y configuraci贸n de herramientas como `ruff`, `pytest`, `mypy`, etc. **En resumen:** - Centraliza la configuraci贸n del proyecto Python. - Lo soportan las herramientas modernas de packaging. - Reduce la cantidad de archivos de configuraci贸n dispersos.
208. 驴C贸mo gestionar dependencias en un proyecto Python moderno? #### Python - aislar el entorno con `venv`; - definir dependencias en `pyproject.toml`; - fijar archivos de bloqueo o restricciones para reproducibilidad; - actualizar regularmente con comprobaciones en CI. **En resumen:** - La gesti贸n de dependencias debe ser reproducible. - No mezcles paquetes globales y del proyecto. - Haz las actualizaciones de forma controlada mediante pruebas.
209. 驴C贸mo organizar correctamente la estructura de un proyecto Python grande? #### Python - dividir el c贸digo en paquetes de dominio; - tener capas separadas: `api`, `services`, `domain`, `infrastructure`; - separar `tests/`, `scripts/`, `configs/`; - mantener l铆mites claros entre m贸dulos y una API p煤blica expl铆cita. **En resumen:** - La estructura debe reflejar el dominio, no detalles t茅cnicos accidentales. - Los l铆mites claros reducen dependencias c铆clicas. - Las pruebas y las herramientas deben ser una parte de primera clase del 谩rbol.
210. 驴Cu谩l es la diferencia entre las pruebas automatizadas y las manuales, y cu谩les son las ventajas de las pruebas automatizadas? #### Python Las pruebas manuales las realiza una persona paso a paso. Las pruebas automatizadas las ejecutan scripts o marcos de pruebas. **En resumen:** - Las pruebas autom谩ticas son r谩pidas, repetibles y aptas para CI. - Las pruebas manuales son 煤tiles para escenarios exploratorios de UX. - En producci贸n hace falta una combinaci贸n de ambos enfoques.
211. 驴Qu茅 es TDD (Test-Driven Development)? #### Python TDD es un ciclo: escribir una prueba que falla -> implementaci贸n m铆nima -> refactorizaci贸n. **En resumen:** - TDD moldea la API a trav茅s de pruebas. - Da retroalimentaci贸n r谩pida sobre regresiones. - Funciona mejor para l贸gica de negocio modular.
212. 驴Qu茅 marcos de pruebas populares existen en Python? #### Python Los m谩s populares son `pytest`, `unittest` de la biblioteca est谩ndar y tambi茅n `hypothesis` para pruebas basadas en propiedades. **En resumen:** - `pytest` es la opci贸n m谩s habitual en proyectos nuevos. - `unittest` es 煤til como herramienta base est谩ndar. - `hypothesis` refuerza la cobertura de casos l铆mite.
213. 驴Qu茅 es `unittest` en Python? #### Python `unittest` es el marco xUnit integrado para pruebas: clases de caso de prueba, m茅todos de aserci贸n, preparaci贸n/limpieza y ejecutor de pruebas. **En resumen:** - Forma parte de la biblioteca est谩ndar. - Encaja en entornos conservadores sin dependencias externas. - Tiene una sintaxis m谩s ceremonial que `pytest`.
214. 驴Qu茅 es `pytest` y en qu茅 se diferencia de `unittest` por sintaxis y funcionalidad? #### Python `pytest` es un marco con sintaxis simple para pruebas funcionales, fixtures potentes, parametrizaci贸n y un ecosistema de complementos. **En resumen:** - `pytest` requiere menos c贸digo repetitivo y es m谩s c贸modo para suites grandes. - `unittest` est谩 basado en clases y es est谩ndar en la biblioteca est谩ndar. - En proyectos modernos suele dominar `pytest`.
215. Describa c贸mo se usa `pytest.raises` para comprobar que aparece una excepci贸n concreta en c贸digo Python. #### Python `pytest.raises(ExpectedError)` comprueba que un bloque de c贸digo lanza exactamente la excepci贸n esperada. ```python import pytest with pytest.raises(ValueError): int("abc") ``` **En resumen:** - Prueba escenarios negativos de forma expl铆cita. - Protege contra el paso silencioso de errores. - Tambi茅n puede verificar el mensaje o atributos de la excepci贸n.
216. 驴Qu茅 es la parametrizaci贸n en pruebas y c贸mo la soporta pytest con `@pytest.mark.parametrize`? #### Python La parametrizaci贸n ejecuta una prueba con varios conjuntos de datos de entrada. En pytest se hace con el decorador `@pytest.mark.parametrize`. **En resumen:** - Menos duplicaci贸n de c贸digo de prueba. - Facilita escalar casos. - Da m谩s transparencia sobre la cobertura de escenarios de entrada.
217. 驴C贸mo definir nombres propios de pruebas parametrizadas en pytest para mejorar la legibilidad? #### Python Usa el par谩metro `ids` en `parametrize`. ```python @pytest.mark.parametrize("value,expected", [(2, True), (3, False)], ids=["even", "odd"]) ``` **En resumen:** - `ids` hace m谩s clara la salida de la ejecuci贸n de pruebas. - Facilita diagnosticar fallos. - Es especialmente 煤til con muchos casos.
218. 驴Qu茅 es Arrange/Setup en pruebas y por qu茅 es importante? #### Python Arrange/Setup es la preparaci贸n del estado de prueba: datos, objetos, mocks y entorno. Una buena preparaci贸n hace que la prueba sea determinista. **En resumen:** - Una preparaci贸n inestable produce pruebas inestables. - Una buena preparaci贸n a铆sla la prueba de efectos externos. - Un Arrange claro mejora la legibilidad del escenario.
219. 驴Qu茅 etapas incluye la limpieza final y por qu茅 es importante? #### Python La fase de limpieza final elimina todo lo que cre贸 la prueba: archivos temporales, conexiones, mocks y registros de prueba en la base de datos. **En resumen:** - La limpieza garantiza aislamiento entre pruebas. - Reduce efectos secundarios e inestabilidad. - En pytest es c贸modo hacerlo con finalizadores de fixtures o fixtures con `yield`.
220. 驴Cu谩l es la diferencia entre `setUp()` y `setUpClass()` en unittest? #### Python `setUp()` se ejecuta antes de **cada** m茅todo de prueba. `setUpClass()` (classmethod) se ejecuta **una vez** antes de todas las pruebas de la clase. **En resumen:** - `setUp` sirve para el aislamiento por prueba. - `setUpClass` sirve para recursos compartidos costosos. - Demasiado estado compartido v铆a `setUpClass` puede complicar las pruebas.
221. 驴Qu茅 es un objeto mock y c贸mo ayuda a mejorar la calidad de las pruebas? #### Python Un objeto mock es un objeto sustituto que imita una dependencia y permite controlar el comportamiento o verificar llamadas. **En resumen:** - Los mocks a铆slan la unidad de servicios externos. - Hacen las pruebas m谩s r谩pidas y estables. - Permiten comprobar interacciones, no solo resultados.
222. 驴Cu谩l es la diferencia entre usar `mock.patch` en unittest y `monkeypatch` en pytest para mockear objetos? #### Python `mock.patch` de `unittest.mock` parchea objetos por ruta de importaci贸n y tiene una API completa para verificar llamadas. `monkeypatch` en pytest cambia de forma m谩s simple atributos, variables de entorno o diccionarios durante la prueba. **En resumen:** - `patch` es m谩s potente para escenarios con aserciones sobre mocks. - `monkeypatch` es c贸modo para sustituciones r谩pidas en pruebas. - A menudo se combinan seg煤n el caso.
223. 驴Cu谩l es el prop贸sito del par谩metro `scope` en las fixtures de pytest? #### Python `scope` define el ciclo de vida de una fixture: `function`, `class`, `module`, `package`, `session`. **En resumen:** - Un alcance menor da mejor aislamiento. - Un alcance mayor acelera la ejecuci贸n de suites grandes. - Elegir el alcance es un equilibrio entre velocidad e independencia.
224. 驴Qu茅 es la complejidad algor铆tmica y c贸mo se determina? #### Python La complejidad algor铆tmica eval煤a c贸mo crecen los costes de tiempo y memoria al aumentar el tama帽o de los datos de entrada `n`. **En resumen:** - Se mide la complejidad temporal y espacial. - La evaluaci贸n suele ser asint贸tica. - Ayuda a elegir algoritmos y estructuras de datos.
225. Explique la notaci贸n Big O y su importancia para evaluar la complejidad de algoritmos. #### Python Big O describe el l铆mite superior del crecimiento del coste de un algoritmo con `n` grande, ignorando constantes y t茅rminos menores. **En resumen:** - Big O muestra escalabilidad, no tiempo exacto. - Proporciona un lenguaje para comparar algoritmos. - Es cr铆tica para el rendimiento con grandes vol煤menes.
226. 驴Qu茅 tipos de complejidad algor铆tmica aparecen con m谩s frecuencia? #### Python Las m谩s comunes son `O(1)`, `O(log n)`, `O(n)`, `O(n log n)` y `O(n^2)`. **En resumen:** - `O(n)` y `O(n log n)` son las m谩s t铆picas en tareas aplicadas. - `O(n^2)` o peor suele convertirse en cuello de botella. - Tambi茅n hay que considerar memoria, no solo tiempo.
227. D茅 ejemplos de tareas que se resuelven eficientemente con algoritmos lineales O(n). #### Python Ejemplos: - b煤squeda de m谩ximo o m铆nimo; - filtrado de elementos; - conteo de frecuencias con `Counter`; - comprobaci贸n de condiciones para cada elemento. **En resumen:** - O(n) significa una sola pasada sobre los datos. - Es 贸ptimo para muchas agregaciones. - Los algoritmos lineales escalan bien.
228. 驴C贸mo funciona `lru_cache` y cu谩ndo conviene usarlo? #### Python `functools.lru_cache` guarda en cach茅 los resultados de una funci贸n seg煤n sus argumentos y devuelve el valor ya preparado en llamadas repetidas. **En resumen:** - Es eficaz para funciones puras con entradas repetidas. - No encaja en funciones con efectos secundarios. - `maxsize` controla el tama帽o de la cach茅 en memoria.
229. 驴C贸mo perfilar el rendimiento de c贸digo Python? #### Python Herramientas b谩sicas: - `timeit` para micro-mediciones; - `cProfile`/`pstats` para perfiles a nivel de llamadas; - `py-spy`/`scalene` para an谩lisis m谩s cercanos a producci贸n. **En resumen:** - Optimiza solo despu茅s de medir. - Perfila escenarios de carga realistas. - Fija una l铆nea base antes y despu茅s de los cambios.
230. 驴Cu谩les son las formas principales de optimizar c贸digo Python? #### Python - elegir las estructuras de datos correctas; - reducir la complejidad asint贸tica; - evitar copias innecesarias; - usar generadores o pipelines perezosos; - almacenar en cach茅 c谩lculos costosos; - mover rutas cr铆ticas a C, Rust o NumPy si hace falta. **En resumen:** - La mayor mejora la da el algoritmo, no un ajuste sint谩ctico. - La optimizaci贸n debe apoyarse en perfilado. - No conviene sacrificar legibilidad sin un beneficio medido.
231. 驴Cu谩ndo conviene usar extensiones en C o PyPy? #### Python Las extensiones en C son adecuadas para puntos cr铆ticos de CPU muy concretos y para integrarse con bibliotecas nativas. PyPy conviene cuando c贸digo Python puro de larga duraci贸n se beneficia del JIT. **En resumen:** - Extensi贸n en C: m谩ximo rendimiento a costa de mayor complejidad de compilaci贸n. - PyPy: mejora potencial sin reescribir en C. - La elecci贸n debe basarse en pruebas comparativas de tu carga real.
232. 驴Qu茅 es el perfilado de memoria? #### Python El perfilado de memoria mide d贸nde y cu谩nta memoria consume el c贸digo con el tiempo para encontrar fugas y zonas pesadas. **En resumen:** - Muestra puntos calientes de memoria y picos. - Es 煤til para cargas batch y de datos. - Herramientas: `tracemalloc`, `memory_profiler`, `scalene`.
233. 驴Qu茅 es el GIL (Global Interpreter Lock)? #### Python El GIL es un mecanismo de CPython que permite que solo un hilo ejecute bytecode de Python al mismo tiempo dentro de un proceso. **En resumen:** - El GIL afecta al multihilo en tareas intensivas de CPU. - Para tareas limitadas por I/O, los hilos siguen siendo 煤tiles. - Para paralelismo de CPU, suele usarse `multiprocessing`.
234. 驴C贸mo afecta el GIL a la concurrencia en CPython y qu茅 consecuencias tiene para el multithreading? #### Python Debido al GIL, los hilos en CPython no ejecutan bytecode de Python en paralelo real para c贸digo intensivo de CPU. Se alternan de forma cooperativa. Consecuencias: - para hilos limitados por I/O, el efecto es bueno porque la espera de I/O se solapa; - para tareas intensivas de CPU, la mejora con hilos suele ser limitada. **En resumen:** - El GIL limita el paralelismo de hilos en escenarios intensivos de CPU. - Los hilos siguen siendo 煤tiles para red y disco. - Para CPU, usa procesos o c贸mputo nativo.
235. 驴C贸mo afecta el GIL al rendimiento? #### Python El GIL casi no molesta en tareas limitadas por I/O, pero limita la capacidad de procesamiento de c贸digo Python multihilo intensivo de CPU dentro de un proceso. **En resumen:** - El impacto del GIL depende del tipo de carga. - El c贸digo intensivo de CPU con hilos en CPython a menudo no escala. - La arquitectura debe elegirse seg煤n el perfil de tareas.
236. Explique el concepto de threading en Python y en qu茅 se diferencia de multiprocessing. #### Python `threading` ejecuta varios hilos dentro de un proceso con memoria compartida. `multiprocessing` ejecuta procesos separados con memoria separada. **En resumen:** - Los hilos son m谩s ligeros y c贸modos para tareas limitadas por I/O. - Los procesos dan paralelismo real de CPU. - Los procesos tienen m谩s sobrecarga de IPC y creaci贸n.
237. 驴Cu谩ndo usar multiprocessing en lugar de threading? #### Python Cuando la tarea es intensiva de CPU y necesita usar varios n煤cleos en CPython. Ejemplos: parsing pesado, procesamiento de imagen o v铆deo y c谩lculo num茅rico. **En resumen:** - Intensiva de CPU -> normalmente `multiprocessing`. - Limitada por I/O -> normalmente `threading` o `asyncio`. - Ten en cuenta el coste de serializaci贸n entre procesos.
238. 驴Cu谩l es la diferencia entre concurrencia y paralelismo y cu谩ndo conviene usar cada uno? #### Python La concurrencia es el solapamiento de tareas en el tiempo. El paralelismo es la ejecuci贸n f铆sica simult谩nea de tareas en varios n煤cleos. **En resumen:** - La concurrencia es 煤til para latencias de I/O. - El paralelismo es necesario para c谩lculos intensivos de CPU. - En Python, la herramienta depende del tipo de cuello de botella.
239. 驴Qu茅 es la concurrencia en Python? #### Python La concurrencia en Python es la organizaci贸n de varias tareas para que progresen juntas mediante hilos, asyncio o procesos. **En resumen:** - Trata de gestionar muchas tareas, no necesariamente en paralelo. - Permite aumentar la capacidad de procesamiento en escenarios de I/O. - Requiere dise帽ar bien sincronizaci贸n y cancelaci贸n.
240. 驴Cu谩l es la diferencia entre tareas limitadas por I/O y tareas intensivas de CPU? #### Python Las tareas limitadas por I/O esperan sobre todo red, disco o base de datos. Las tareas intensivas de CPU gastan sobre todo tiempo en c谩lculo del procesador. **En resumen:** - Las tareas limitadas por I/O escalan bien con asyncio o hilos. - Las tareas intensivas de CPU escalan mejor con multiprocessing o c贸digo nativo. - Primero identifica el cuello de botella con perfilado.
241. 驴Para qu茅 sirve el m贸dulo `asyncio` en Python y c贸mo permite implementar programaci贸n as铆ncrona? #### Python `asyncio` proporciona un bucle de eventos, planificaci贸n de tareas y primitivas as铆ncronas para concurrencia cooperativa en tareas limitadas por I/O. **En resumen:** - Permite atender muchas operaciones de I/O de forma eficiente. - Se basa en `async` y `await`. - Encaja bien en servicios y clientes de red.
242. 驴En qu茅 se diferencian la programaci贸n s铆ncrona y la as铆ncrona en Python? #### Python S铆ncrono: una llamada bloquea el hilo actual hasta completarse. As铆ncrono: `await` cede el control al bucle de eventos mientras la operaci贸n espera I/O. **En resumen:** - La asincron铆a reduce el tiempo ocioso durante I/O. - El modelo s铆ncrono es m谩s simple para l贸gica lineal. - La asincron铆a a帽ade complejidad en gesti贸n de tareas y cancelaci贸n.
243. 驴Qu茅 son `async` y `await`? #### Python `async def` define una corrutina. `await` pausa la corrutina hasta que el objeto esperable est茅 listo y devuelve el control al bucle. **En resumen:** - Es la sintaxis de un modelo as铆ncrono cooperativo. - Se usa junto con `asyncio` y bibliotecas as铆ncronas. - `await` solo es v谩lido dentro de `async def`.
244. 驴C贸mo funciona `asyncio`? #### Python `asyncio` ejecuta un bucle de eventos que procesa tareas (corrutinas), cambiando en los puntos `await` y planificando operaciones I/O listas. **Regla cr铆tica:** El bucle de eventos funciona en un solo hilo. Cualquier operaci贸n bloqueante (`time.sleep()`, peticiones s铆ncronas con `requests`, c谩lculos pesados) detiene **todo** el ciclo y todas las dem谩s tareas. **En resumen:** - Un hilo puede atender muchas tareas I/O gracias a la cooperaci贸n. - La planificaci贸n no expulsa tareas de forma preventiva. - Las llamadas bloqueantes destruyen el rendimiento de `asyncio`.
245. 驴Qu茅 es el bucle de eventos? #### Python El bucle de eventos es un planificador que sigue eventos o disponibilidad de I/O y ejecuta las devoluciones de llamada o corrutinas correspondientes. **En resumen:** - Es el componente central del modelo de `asyncio`. - Gestiona el ciclo de vida de las tareas as铆ncronas. - Determina cu谩ndo cada corrutina contin煤a ejecut谩ndose.
246. 驴C贸mo permite `asyncio` implementar programaci贸n as铆ncrona y qu茅 componentes principales intervienen en c贸digo asyncio? #### Python Componentes clave: - bucle de eventos; - corrutina (`async def`); - tarea (`asyncio.create_task`); - objetos esperables (futures, tareas, corrutinas); - primitivas de sincronizaci贸n (`Lock`, `Queue`, `Semaphore`). **En resumen:** - `asyncio` combina planificaci贸n y API as铆ncrona en un solo modelo. - Las tareas comparten un hilo de ejecuci贸n de forma cooperativa. - La arquitectura debe tener en cuenta tiempos de espera, reintentos y cancelaci贸n.
247. 驴Cu谩ndo `asyncio` no aporta ventajas? #### Python Cuando la carga es intensiva de CPU o las bibliotecas principales son bloqueantes y no tienen API as铆ncrona. Tampoco compensa en scripts simples y cortos. **Soluci贸n para c贸digo bloqueante:** Si necesitas usar una biblioteca bloqueante en un entorno as铆ncrono, usa `loop.run_in_executor(None, sync_func)`, que la ejecutar谩 en un hilo aparte sin bloquear el bucle de eventos. **En resumen:** - La asincron铆a no acelera c谩lculos puros. - Sin bibliotecas I/O no bloqueantes, la ganancia es m铆nima. - `run_in_executor` ayuda a integrar c贸digo heredado o s铆ncrono. - La complejidad as铆ncrona debe justificarse por la carga.
248. 驴C贸mo funciona la cancelaci贸n en asyncio? #### Python La cancelaci贸n de una tarea (`task.cancel()`) lanza `CancelledError` dentro de la corrutina. El c贸digo debe manejar correctamente la limpieza en `try/finally`. **En resumen:** - La cancelaci贸n es un flujo de control normal en c贸digo as铆ncrono. - Hay que dise帽ar las corrutinas teniendo en cuenta la cancelaci贸n. - Ignorar la cancelaci贸n lleva a tareas colgadas.
249. 驴Qu茅 es `contextvars`? #### Python `contextvars` proporciona variables locales al contexto, seguras para escenarios as铆ncronos e hilos. Es 煤til para identificador de solicitud, identificador de correlaci贸n y contexto de inquilino. **En resumen:** - Es una alternativa al estado global en c贸digo concurrente. - El valor queda aislado por contexto. - Mejora el trazado y la observabilidad.
250. 驴Qu茅 buenas pr谩cticas conviene aplicar al escribir c贸digo Python? #### Python - seguir PEP 8 y automatizar el formateo; - escribir anotaciones de tipos expl铆citas para la API p煤blica; - usar `with` para recursos; - cubrir la l贸gica de negocio con pruebas; - evitar la optimizaci贸n prematura y perfilar; - mantener m贸dulos peque帽os con responsabilidad clara; - gestionar dependencias mediante `pyproject.toml` y una estrategia de bloqueo. **En resumen:** - La legibilidad y la previsibilidad importan m谩s que los "trucos". - La calidad se sostiene en la automatizaci贸n: an谩lisis est谩tico, tipos, pruebas y CI. - La simplicidad arquitect贸nica reduce el coste de mantenimiento.