Fundamentos de Programación y Python

1

¿Por qué aprender Python?

2

Introducción a Python

3

Conceptos Básicos de Programación

4

Práctica: Te doy la bienvenida a los ejercicios interactivos

5

Manipulación de Cadenas de Texto en Python

6

Enteros, Flotantes y Booleanos

7

Todo lo que Debes Saber sobre print en Python

8

Operaciones Matemáticas en Python

9

Operaciones de Entrada/Salida en Consola

Colección y Procesamiento de Datos en Python

10

Listas

11

Método slice

12

Listas de más dimensiones y Tuplas

13

Aplicación de Matrices

14

Diccionarios

15

Comprehension Lists en Python (CLASE NUEVA)

Control de Flujo en Python

16

Estructuras condicionales

17

Bucles y Control de Iteraciones

18

Generadores e Iteradores

Funciones y Manejo de Excepciones en Python

19

Uso de Funciones en Python

20

Funciones Lambda y Programación Funcional en Python

21

¿Cómo realizar una función recursiva en Python?

22

Manejo de Excepciones y Uso de Pass (CLASE NUEVA)

Programación Orientada a Objetos en Python

23

Fundamentos de Programación Orientada a Objetos en Python

24

Ejercicio Biblioteca con POO

25

Herencia en POO con Python

26

Objetos heredados

27

Los 4 pilares de la programacion orientada a objetos

28

Uso de super() en Python (CLASE NUEVA)

29

Superando los Fundamentos de Programación Orientada a Objetos en Python

Lectura y escritura de archivos

30

Manejo de Archivos .TXT (CLASE NUEVA)

31

Manejo de Archivos CSV (CLASE NUEVA)

32

Manejo de Archivos JSON (CLASE NUEVA)

Biblioteca estándar de Python

33

Biblioteca estándar en Python (CLASE NUEVA)

34

Librería Os, Math y Random (CLASE NUEVA)

35

Librería Statistics y Análisis Estadístico (CLASE NUEVA)

36

Proyecto final: Guerra naval

Conceptos avanzados de Python

37

Recapitulación de lo aprendido hasta ahora

38

Escribir código Pythonico y profesional

39

Comentarios y Docstrings en Python

40

Scope y closures: variables locales y globales

41

Anotaciones de tipo

42

Validación de tipos en métodos

43

Librería Collections y Enumeraciones

Decoradores

44

Decoradores en Python

45

Decoradores anidados y con parámetros

46

Uso de Decoradores en clases y métodos

Métodos y estructura de clases en Python

47

Métodos mágicos

48

Sobrecarga de operadores

49

Implementación de `if __name__ == "__main__":`

50

Metaprogramación en Python

51

Uso de *args y **kwargs

52

Métodos privados y protegidos

53

Gestión avanzada de propiedades

54

Métodos estáticos y de clase avanzados

Programación concurrente y asíncrona

55

Introducción a la concurrencia y paralelismo

56

Threading y multiprocessing en Python

57

Asincronismo con asyncio

58

Asincronismo y concurrencia

Creación de módulos y paquetes

59

Creación de módulos en Python

60

Gestión de paquetes

61

Publicación de paquetes en PyPI

Proyecto final

62

Implementación de un sistema completo

63

Implementación de un Sistema Completo

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso de Python

Curso de Python

Carli Code

Carli Code

Métodos mágicos

47/63
Recursos

Aportes 6

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

varias de las clases tienen errores de edicion. Tanto la produccion como el contenido de esta segunda parte del curso se siente como si lo hubiesen hecho a los apuros. O al menos así lo percibo yo
Imagina que tienes una caja de juguetes muy especial. Esta caja tiene algunos juguetes mágicos que pueden hacer cosas increíbles cuando juegas con ellos de ciertas maneras. Los métodos mágicos en Python son como esos juguetes especiales. Son funciones que empiezan y terminan con dos guiones bajos (`__`) y permiten que los objetos de tus clases hagan cosas mágicas. Por ejemplo, cuando sumas dos números con el signo `+`, Python usa un método mágico llamado `__add__` `Ejemplo:` ```python class Juguete: def __init__(self, nombre): self.nombre = nombre def __add__(self, otro_juguete): return Juguete(self.nombre + " y " + otro_juguete.nombre) # Crear dos juguetes juguete1 = Juguete("Carro") juguete2 = Juguete("Avión") # Usar el método mágico __add__ para "sumar" los juguetes juguete3 = juguete1 + juguete2 print(juguete3.nombre) # Salida: Carro y Avión ```
Los \*\*métodos mágicos\*\* en Python (también llamados "métodos especiales" o "dunder methods" por la doble subrayado que los rodea) son funciones predefinidas en las clases que permiten personalizar el comportamiento de los objetos en varias situaciones, como en operaciones matemáticas, conversiones de tipos, comparaciones y manejo de contenedores. Estos métodos comienzan y terminan con doble subrayado (`\_\_`), por ejemplo, `\_\_init\_\_` o `\_\_str\_\_`. Al definir estos métodos, se le puede indicar a Python cómo debe comportarse un objeto en distintos contextos. \### 1. Métodos de Inicialización y Representación \- \*\*`\_\_init\_\_(self, ...)`\*\*: Inicializador de una clase (similar a un constructor). Se ejecuta al crear una instancia. \- \*\*`\_\_str\_\_(self)`\*\*: Define el comportamiento del objeto cuando se convierte a una cadena con `str()`, como al usar `print()`. \- \*\*`\_\_repr\_\_(self)`\*\*: Representación oficial del objeto, útil para depuración. A menudo se usa en lugar de `\_\_str\_\_` para generar un mensaje detallado y debe proporcionar una salida que permita recrear el objeto cuando se usa `eval()`. ```python class Persona: def \_\_init\_\_(self, nombre, edad): self.nombre = nombre self.edad = edad def \_\_str\_\_(self): return f"Persona({self.nombre}, {self.edad})" def \_\_repr\_\_(self): return f"Persona(nombre={self.nombre!r}, edad={self.edad})" persona = Persona("Ana", 30) print(persona) # Salida personalizada repr(persona) # Representación oficial para depuración ``` \### 2. Métodos de Operadores Aritméticos Permiten personalizar el comportamiento de operadores (`+`, `-`, `\*`, `/`, etc.). \- \*\*`\_\_add\_\_(self, other)`\*\*: Define el comportamiento de la adición (`self + other`). \- \*\*`\_\_sub\_\_(self, other)`\*\*: Define la resta (`self - other`). \- \*\*`\_\_mul\_\_(self, other)`\*\*: Define la multiplicación (`self \* other`). \- \*\*`\_\_truediv\_\_(self, other)`\*\*: Define la división (`self / other`). ```python class Vector: def \_\_init\_\_(self, x, y): self.x = x self.y = y def \_\_add\_\_(self, other): return Vector(self.x + other.x, self.y + other.y) def \_\_str\_\_(self): return f"Vector({self.x}, {self.y})" v1 = Vector(2, 3) v2 = Vector(1, 5) print(v1 + v2) # Salida: Vector(3, 8) ``` \### 3. Métodos de Comparación Permiten especificar el comportamiento para comparaciones (`==`, `<`, `>`, etc.). \- \*\*`\_\_eq\_\_(self, other)`\*\*: Define la comparación de igualdad (`self == other`). \- \*\*`\_\_lt\_\_(self, other)`\*\*: Define la comparación de "menor que" (`self < other`). \- \*\*`\_\_le\_\_(self, other)`\*\*: Define la comparación de "menor o igual" (`self <= other`). ```python class Persona: def \_\_init\_\_(self, nombre, edad): self.nombre = nombre self.edad = edad def \_\_eq\_\_(self, other): return self.edad == other.edad def \_\_lt\_\_(self, other): return self.edad < other.edad persona1 = Persona("Juan", 25) persona2 = Persona("Ana", 30) print(persona1 == persona2) # Salida: False print(persona1 < persona2) # Salida: True ``` \### 4. Métodos de Acceso a Elementos Permiten definir el comportamiento de acceso, modificación y eliminación de elementos en objetos como si fueran contenedores. \- \*\*`\_\_getitem\_\_(self, key)`\*\*: Define el comportamiento al acceder a un elemento (`self\[key]`). \- \*\*`\_\_setitem\_\_(self, key, value)`\*\*: Define el comportamiento al asignar un valor (`self\[key] = value`). \- \*\*`\_\_delitem\_\_(self, key)`\*\*: Define el comportamiento al eliminar un elemento (`del self\[key]`). ```python class Contenedor: def \_\_init\_\_(self): self.datos = {} def \_\_getitem\_\_(self, key): return self.datos.get(key, None) def \_\_setitem\_\_(self, key, value): self.datos\[key] = value def \_\_delitem\_\_(self, key): del self.datos\[key] cont = Contenedor() cont\["a"] = 10 print(cont\["a"]) # Salida: 10 del cont\["a"] ``` \### 5. Métodos de Contexto (con `with`) Permiten definir el comportamiento al usar un objeto con el bloque `with`, como al manejar archivos. \- \*\*`\_\_enter\_\_(self)`\*\*: Inicializa o prepara el objeto para el contexto. \- \*\*`\_\_exit\_\_(self, exc\_type, exc\_val, exc\_tb)`\*\*: Define el comportamiento al salir del contexto, manejando cualquier excepción. ```python class Archivo: def \_\_init\_\_(self, nombre): self.nombre = nombre self.archivo = None def \_\_enter\_\_(self): self.archivo = open(self.nombre, "w") return self.archivo def \_\_exit\_\_(self, exc\_type, exc\_val, exc\_tb): if self.archivo: self.archivo.close() with Archivo("ejemplo.txt") as f: f.write("Texto de ejemplo") ``` \### Resumen Los métodos mágicos permiten una gran personalización y facilitan la creación de clases que se comportan de forma coherente con los operadores y funciones de Python. Al definir estos métodos, puedes hacer que las clases respondan a operaciones y funciones nativas de Python, logrando una sintaxis más intuitiva y adaptada a tus necesidades.
**El código de la *clase*:** ```python class Persona: def __init__(self, nombre: str, edad: int): self.nombre = nombre self.edad = edad def __str__(self) -> str: # Devuelve una representación amigable para el usuario return f"Persona: {self.nombre}, {self.edad} años" def __repr__(self) -> str: # Devuelve una representación detallada del objeto para depuración return f"Persona(nombre='{self.nombre}', edad={self.edad})" def __eq__(self, otra_persona) -> bool: # Compara si dos personas son iguales en función del nombre y la edad return self.nombre == otra_persona.nombre and self.edad == otra_persona.edad def __lt__(self, otra_persona) -> bool: # Compara si una persona es "menor" que otra en función de la edad return self.edad < otra_persona.edad def __add__(self, otra_persona): # Sobrecarga el operador + para sumar las edades de dos personas return self.edad + otra_persona.edad # Crear instancias de Persona p1 = Persona("Ana", 28) p2 = Persona("Luis", 35) p3 = Persona("Ana", 28) # __str__: Representación legible #print(p1) # Output: Persona: Ana, 28 años # __repr__: Representación detallada #print(repr(p2)) # Output: Persona(nombre='Luis', edad=35) # __eq__: Comparación de igualdad #print(p1 == p3) # Output: True (son iguales en nombre y edad) # __lt__: Comparación "menor que" por edad #print(p1 < p2) # Output: True (porque 28 es menor que 35) # __add__: Sumar edades de dos personas print(p1 + p2) # Output: 63 (28 + 35) ```
los raltivos a !=, >=, >, <=       ```python def __ne__(self, otra_persona): return self.nombre != otra_persona.nombre and self.edad != otra_persona.edad def __lt__(self, otra_persona): return self.edad < otra_persona.edad def __le__(self, otra_persona): return self.edad <= otra_persona.edad def __gt__(self, otra_persona): return self.edad > otra_persona.edad def __ge__(self, otra_persona): return self.edad >= otra_persona.edad ```
```js class frac: def __init__(self,numerator:int,denominator:int): if not isinstance(numerator,int) or not isinstance(denominator,int): raise TypeError('denominator and numerator must be int') elif denominator==0: raise ValueError('el infinito es inalcanzable no dividas en 0') self.num=numerator self.den=denominator def __str__(self): return f'{self.num}/{self.den}' def __repr__(self): return f'numerator: {self.num}, denominator:{self.den}' def __sub__(self,other): if not isinstance(other,frac): raise TypeError(f'{other} is not a fraction') newDen=self.den*other.den newNum=other.den*self.num-self.den*other.num return frac(newNum,newDen) a= frac(4,6) b= frac(64,34) print (f'a is {a}') print('b is',repr(b)) c=a-b print (c) ```class frac:    def \_\_init\_\_(self,numerator:int,denominator:int):        if not isinstance(numerator,int) or not isinstance(denominator,int):            raise TypeError('denominator and numerator must be int')        elif denominator==0:            raise ValueError('el infinito es inalcanzable no dividas en 0')        self.num=numerator        self.den=denominator    def \_\_str\_\_(self):        return f'{self.num}/{self.den}'    def \_\_repr\_\_(self):        return f'numerator: {self.num}, denominator:{self.den}'    def \_\_sub\_\_(self,other):        if not isinstance(other,frac):            raise TypeError(f'{other} is not a fraction')        newDen=self.den\*other.den        newNum=other.den\*self.num-self.den\*other.num        return frac(newNum,newDen)    a= frac(4,6)b= frac(64,34)print (f'a is {a}')print('b is',repr(b))c=a-bprint (c)