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 se trata de lo que quieres comprar, sino de quién quieres ser. Aprovecha el precio especial.

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

15 Días
14 Hrs
34 Min
58 Seg
Curso de Python

Curso de Python

Carli Code

Carli Code

Sobrecarga de operadores

48/63

Lectura

Sobrecarga de operadores

DALLE_2024-10-16_17.14.59_-A_visual_representation_of_Operator_Overloading_in_Python.The_image_should_depict_Python_code_snippets_where_operators_like-and.jpg

Imagina que puedes hacer que tus clases personalizadas en Python se comporten como números, listas o cadenas de texto, permitiendo sumar objetos, compararlos y mucho más. ¿Qué pasaría si pudieras redefinir cómo tus clases responden a operaciones comunes como +, -, ==, o incluso <? Esa es la magia de la sobrecarga de operadores.

...

Regístrate o inicia sesión para leer el resto del contenido.

Aportes 6

Preguntas 0

Ordenar por:

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

Sé que quizá sea mucho pedir o algunos no lo vean como algo relevante, también sé que mucho del aprendizaje depende de uno mismo buscar respuestas, pero en el caso de los métodos y muchas cosas que se abrevian, siempre sería bueno que los profes añadieran como contenido extra en sus clases al explicar los métodos **"Aquí usamos LT, por Less Than (menor qué en inglés)"**. Esto aportaría un poco más de **riqueza en el conocimiento** de python ya que en nuestra mente realizamos asociaciones con lo que significa cada método y es **más fácil recordarlo**.
### **Ordenar objetos con** `__lt__` Al implementar `__lt__`, tus objetos se pueden ordenar directamente utilizando funciones como `sorted()` o estructuras como `list.sort()`. ```python personas = [Persona("Carlos", 28), Persona("Julian", 30), Persona("Ana", 25)] personas_ordenadas = sorted(personas) # Ordena automáticamente usando __lt__ for persona in personas_ordenadas: print(persona.nombre, persona.edad) # Salida: # Ana 25 # Carlos 28 # Julian 30 ```personas = \[Persona("Carlos", 28), Persona("Julian", 30), Persona("Ana", 25)] personas\_ordenadas = sorted(personas) # Ordena automáticamente usando \_\_lt\_\_ for persona in personas\_ordenadas: print(persona.nombre, persona.edad) \# Salida: \# Ana 25 \# Carlos 28 \# Julian 30
os métodos especiales (o "métodos mágicos") como `__eq__`, `__repr__` y `__add__` son parte del modelo de datos de Python y permiten definir o personalizar el comportamiento de objetos en ciertas operaciones. A continuación, te explico cada uno: ### `__eq__`: Comparación de igualdad Este método se utiliza para definir cómo se compara un objeto con otro utilizando el operador `==`. #### Ejemplo: ```python class Persona: def __init__(self, nombre, edad): self.nombre = nombre self.edad = edad def __eq__(self, otro): return self.nombre == otro.nombre and self.edad == otro.edad p1 = Persona("Julian", 30) p2 = Persona("Julian", 30) p3 = Persona("Ana", 25) print(p1 == p2) # True, porque tienen el mismo nombre y edad print(p1 == p3) # False, porque son diferentes ```**Por defecto:** Sin implementar `__eq__`, Python verifica si dos objetos son el mismo (tienen la misma referencia en memoria). **Personalizado:** Puedes implementar lógica específica para determinar cuándo dos objetos deben considerarse iguales. ### `__repr__`: Representación oficial del objeto Este método define la forma en que un objeto se representa como cadena, generalmente para depuración y desarrollo. Se utiliza al llamar a `repr(objeto)` o al imprimir un objeto en contextos como la consola. #### Ejemplo: ```python class Persona: def __init__(self, nombre, edad): self.nombre = nombre self.edad = edad def __repr__(self): return f"Persona(nombre='{self.nombre}', edad={self.edad})" p = Persona("Julian", 30) print(repr(p)) # Persona(nombre='Julian', edad=30) print(p) # Persona(nombre='Julian', edad=30) (si no se implementa __str__, __repr__ se usa por defecto) ```**Recomendación:** `__repr__` debe devolver una cadena que permita reconstruir el objeto, si es posible. ### `__add__`: Operador de suma (`+`) Este método define el comportamiento del operador `+` cuando se utiliza con instancias de la clase. #### Ejemplo: ```python class Vector: def __init__(self, x, y): self.x = x self.y = y def __add__(self, otro): return Vector(self.x + otro.x, self.y + otro.y) def __repr__(self): return f"Vector({self.x}, {self.y})" v1 = Vector(1, 2) v2 = Vector(3, 4) v3 = v1 + v2 # Llama a __add__ print(v3) # Vector(4, 6) ```**Por defecto:** Si no se implementa, usar `+` con objetos personalizados lanza un error. **Personalizado:** Puedes definir cómo combinar los atributos de dos objetos (como sumar vectores, concatenar datos, etc.). ### `__lt__`**: Menor que** #### ¿Qué hace? * Define cómo se compara un objeto con otro utilizando el operador `<`. * Devuelve `True` si el objeto actual es "menor que" el otro objeto, de acuerdo con la lógica personalizada que implementes; de lo contrario, devuelve `False`. ### **Ejemplo sencillo:** Vamos a definir una clase `Persona` donde los objetos se comparan por su edad. ```python class Persona: def __init__(self, nombre, edad): self.nombre = nombre self.edad = edad def __lt__(self, otro): return self.edad < otro.edad p1 = Persona("Julian", 30) p2 = Persona("Ana", 25) print(p1 < p2) # False, porque Julian (30) no es menor que Ana (25) print(p2 < p1) # True, porque Ana (25) es menor que Julian (30) ```**Relación con otros métodos de comparación** El método `__lt__` es uno de los métodos de comparación "ricos", junto con: MétodoOperadorSignificado`__lt__<`Menor que`__le__<=`Menor o igual que`__gt__>`Mayor que`__ge__>=`Mayor o igual que`__eq__==`Igualdad`__ne__!=`Desigualdad Si implementas algunos de estos métodos, puedes personalizar completamente el comportamiento de comparación de tu clase.
la imagen no tiene ningún tipo de sentido, es claro que se hizo con IA, pero se ve curiosita
CASOS DE USO: La sobrecarga de operadores en Python permite definir cómo los operadores (como `+`, `-`, `*`, etc.) deben comportarse cuando se aplican a objetos de una clase personalizada. Aquí tienes algunos casos de uso comunes: 1. **Operaciones Matemáticas Personalizadas**: * **Vectores**: Puedes definir cómo sumar, restar o multiplicar vectores. ```js 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) v1 = Vector(1, 2) v2 = Vector(3, 4) v3 = v1 + v2 # Vector(4, 6 ```**Concatenación de Objetos**: * **Cadenas de Texto**: Puedes definir cómo concatenar objetos que representan cadenas de texto de manera personalizada. ```js class Cadena: def __init__(self, texto): self.texto = texto def __add__(self, other): return Cadena(self.texto + other.texto) c1 = Cadena("Hola, ") c2 = Cadena("mundo!") c3 = c1 + c2 # Cadena("Hola, mundo!") ```**Comparación de Objetos**: * **Fechas**: Puedes definir cómo comparar objetos que representan fechas. ```js class Fecha: def __init__(self, dia, mes, año): self.dia = dia self.mes = mes self.año = año def __eq__(self, other): return (self.dia == other.dia and self.mes == other.mes and self.año == other.año) f1 = Fecha(28, 10, 2024) f2 = Fecha(28, 10, 2024) print(f1 == f2) # True ```
La \*\*sobrecarga de operadores\*\* en Python permite redefinir el comportamiento de los operadores estándar (como `+`, `-`, `\*`, `==`, etc.) para que puedan ser usados con objetos de una clase personalizada. A través de los \*\*métodos especiales\*\* (también conocidos como "métodos mágicos" o "dunder methods"), Python permite implementar esta funcionalidad en clases, facilitando la creación de clases con operaciones específicas. \### Ejemplo básico de sobrecarga de operadores Supongamos que queremos una clase `Vector` que represente un vector en un plano 2D. Podríamos querer sumar dos instancias de `Vector` con el operador `+`, pero por defecto Python no sabe cómo hacer esta operación entre objetos de esta clase. Implementaríamos el método especial `\_\_add\_\_` para que la suma funcione: ```python class Vector: def \_\_init\_\_(self, x: int, y: int): self.x = x self.y = y def \_\_add\_\_(self, other): if isinstance(other, Vector): return Vector(self.x + other.x, self.y + other.y) raise TypeError("El operando debe ser de tipo Vector") def \_\_str\_\_(self): return f"Vector({self.x}, {self.y})" v1 = Vector(2, 3) v2 = Vector(5, 7) v3 = v1 + v2 # Esto llama a v1.\_\_add\_\_(v2) print(v3) # Salida: Vector(7, 10) ``` Aquí el método `\_\_add\_\_` permite usar `+` para sumar dos vectores, devolviendo un nuevo objeto `Vector`. \### Métodos especiales para sobrecargar operadores Existen varios métodos especiales en Python para sobrecargar distintos operadores. Aquí tienes una lista de algunos operadores y los métodos correspondientes: 1\. \*\*Operadores Aritméticos\*\*: \- `+` : `\_\_add\_\_(self, other)` \- `-` : `\_\_sub\_\_(self, other)` \- `\*` : `\_\_mul\_\_(self, other)` \- `/` : `\_\_truediv\_\_(self, other)` \- `//` : `\_\_floordiv\_\_(self, other)` \- `%` : `\_\_mod\_\_(self, other)` \- `\*\*` : `\_\_pow\_\_(self, other)` 2\. \*\*Operadores de Comparación\*\*: \- `==` : `\_\_eq\_\_(self, other)` \- `!=` : `\_\_ne\_\_(self, other)` \- `<` : `\_\_lt\_\_(self, other)` \- `<=` : `\_\_le\_\_(self, other)` \- `>` : `\_\_gt\_\_(self, other)` \- `>=` : `\_\_ge\_\_(self, other)` 3\. \*\*Operadores de Asignación Aritmética\*\*: \- `+=` : `\_\_iadd\_\_(self, other)` \- `-=` : `\_\_isub\_\_(self, other)` \- `\*=` : `\_\_imul\_\_(self, other)` \- `/=` : `\_\_itruediv\_\_(self, other)` 4\. \*\*Conversión de Tipos\*\*: \- `\_\_int\_\_(self)` para `int()` \- `\_\_float\_\_(self)` para `float()` \- `\_\_str\_\_(self)` para `str()` \### Ejemplo completo con varios operadores Aquí tienes un ejemplo con una clase `Complejo` que representa números complejos, sobrecargando operadores aritméticos y de comparación: ```python class Complejo: def \_\_init\_\_(self, real: float, imag: float): self.real = real self.imag = imag def \_\_add\_\_(self, other): if isinstance(other, Complejo): return Complejo(self.real + other.real, self.imag + other.imag) raise TypeError("El operando debe ser de tipo Complejo") def \_\_sub\_\_(self, other): if isinstance(other, Complejo): return Complejo(self.real - other.real, self.imag - other.imag) raise TypeError("El operando debe ser de tipo Complejo") def \_\_mul\_\_(self, other): if isinstance(other, Complejo): real = self.real \* other.real - self.imag \* other.imag imag = self.real \* other.imag + self.imag \* other.real return Complejo(real, imag) raise TypeError("El operando debe ser de tipo Complejo") def \_\_eq\_\_(self, other): return self.real == other.real and self.imag == other.imag def \_\_str\_\_(self): return f"({self.real} + {self.imag}i)" c1 = Complejo(2, 3) c2 = Complejo(1, -1) print(c1 + c2) # Salida: (3 + 2i) print(c1 - c2) # Salida: (1 + 4i) print(c1 \* c2) # Salida: (5 + 1i) print(c1 == c2) # Salida: False ``` \### Consideraciones al Sobrecargar Operadores 1\. \*\*Compatibilidad\*\*: Al implementar métodos de sobrecarga, asegúrate de manejar correctamente errores de tipo, como en `isinstance()` para verificar tipos de entrada. 2\. \*\*Inmutabilidad vs. Mutabilidad\*\*: Decide si los métodos devuelven nuevos objetos o modifican el objeto en sí, ya que puede afectar el uso de instancias en el programa. 3\. \*\*Legibilidad\*\*: Usa sobrecarga solo cuando el significado del operador sea intuitivo para la clase; sobrecargar sin una lógica clara puede causar confusión en el código. Sobrecargar operadores permite hacer que los objetos sean más expresivos y fáciles de manipular, lo cual resulta útil en programas complejos donde el uso de operadores personalizados aumenta la legibilidad y reduce errores.