La programación orientada a objetos (POO) es un paradigma de programación (estilo o forma de programar) que se basa en la utilización de objetos similares a los de la vida real, con sus características y comportamiento.
Python es un lenguaje orientado a objetos. Un objeto se caracteriza por tener propiedades y métodos o dicho de otra forma, datos y código. La propiedades describen el estado del objeto y los métodos aportan funcionalidad al mismo.
Estudiaremos un ejemplo para entender mejor los conceptos de clase y objeto: “Una aplicación Python necesita trabajar con datos de los empleados de una empresa. De cada empleado se debe registrar un identificador, nombre, apellidos, fecha de nacimiento, salario y fecha de alta en la empresa”.
Clases y objetos. Propiedades, atributos y métodos.
La POO es un paradigma de programación o estilo de programar el cual se basa en el uso de objetos similares a los de la vida real con sus caracteristicas y comportamiento.
Python es un lenguaje orientado a objetos LOO, y un objeto se caracteriza por tener propiedades y métodos.
Vamos a ver un ejemplo:
“Una aplicación Python necesita trabajar con datos de los empleados de una empresa. De cada empleado se debe registrar un identificador, nombre, apellidos, fecha de nacimiento, salario y fecha de alta en la empresa”

En ejemplo anterior la clase sería –> Empleado y las características o atributos (Id_empleado, nombre, apellidos, Fecha_nacimiento, salario, fecha_alta). Una clase la podemos asemejar a una plantilla en base a la cual se construyen objetos.
El proceso de crear objetos se conoce como instanciación. Un objeto es una instancia de una clase.
La POO facilita la reutilización del código, la organización modular de las aplicaciones y el encapsulamiento.
Atributos y métodos.
Los atributos o propiedades de un objeto determinan el estado del mismo. Los métodos son acciones que puede llevar a cabo un objeto y que pueden alterar o no su estado.
Los métodos son funciones que se definen en la clase y pueden servir para instanciar (crear) el objeto, obtener o retornar el valor de algún atributo, o interactuar con otros objetos.
Veamos otro ejemplo de una aplicación que debe trabajar con vehículos. Creamos la clase «Vehiculo», y sus atributos. Y en ella, añadimos los métodos «es_diesel» y «letras_matricula» el cual nos retornan si es diesel o no y las letras de la matrícula.

Pongamos por ejemplo:
El vehículo con matrícula 1234-ABC, marca Ford, modelo Focus, potencia 130CV, y diesel sería un objeto perteneciente a la clase «Vehiculo» creada.
La abstracción es un concepto básico de la POO, ya que mediante la misma un usuario final de una clase puede utilizar sus métodos sin la necesidad de conocer cómo han sido desarrollados o implementa
Creamos clases en Python. Método constructor.
Las clases en python se crean dentro de un módulo, mediante la extensión .py, y en la misma puede contener definición de funciones, clases, variables, etc.
Veamos un ejemplo, con el módulo -> clases.py, donde se define la clase Empleado con el método constructor. El método constructor se utiliza para crear o instanciar un objeto de una clase. En el momento en que se llama al constructor se reserva memoria para el objeto y se asignan valores iniciales a sus atributos.
class Empleado: def __init__(self, nombre, salario, correo, telefono): self.nombre = nombre self.salario = salario self.correo = correo self. telefono = telefono def aumentar_salario(self, porcentaje): self.salario = self.salario + self.salario * porcentaje
Cada clase se define a partir de la palabra reservada class seguida del nombre de la clase «Empleado» en el ejemplo. La clase se escribe siempre el primer carácter en mayúscula.
La función __init__() es el método constructor de la clase. Esta función tiene varios argumentos:
- self hace referencia al propio objeto el cual se está creando.
- El resto de argumentos guardan los valores que se darán a cada uno de los atributos del objeto que se crea.
- Por norma, y por ser más intuitivo, se suele usar el mismo nombre para argumentos y atributos. Dentro del constructor los atributos van precedidos de la palabra reservada self.
A continuación vemos como crear objetos de la clase Empleado (En ese momento es cuando se reserva memoria para los objetos):
#Creamos objetos de la clase Empleado #En primer lugar importamos la clase Empleado desde el modulo clases.py from clases import Empleado # Y creamos (instanciamos) los objetos empleado1 y empleado2 dando valores a sus atributos empleado1 = Empleado("Perico", 6000, "perico@palotes.com", "456987123") empleado2 = Empleado("Armando", 5000, "armando@bronca.com", "789123654") #Impresión de algún atributo print(empleado1.nombre) #La salida es: Perico
- Observa cómo al crear un empleado se escribe el nombre de la clase
(Empleado) y entre paréntesis los valores que se asignan a cada atributo, en
el mismo orden en el que se especificaron en el constructor. En realidad se
está llamando al método constructor. - En las llamadas no se le da valor al parámetro “self” explícitamente.
- Por último, en la sentencia “print” se muestra el nombre del objeto
“empleado1”.
Existe la posibilidad de asignar un valor por defecto a los atributos de una clase, en
este caso el constructor no suele llevar argumento para ese atributo.
Autoevaluación.- 1

#En primer lugar he creado el módulo --> clases.py la creació de la clase Partido. class Partido: def __init__(self, eqLocal, eqVisitante, puntosLocal, puntosVisitante):#Entre paréntesis argumentos #Atributos self.eqLocal = eqLocal self.eqVisintante = eqVisitante self.puntosLocal = puntosLocal self.puntosVisitante = puntosVisitante #A continuación, he creado otro módulo --> creaObjetos.py para instanciar (crear) objetos. #Primero creamos la importación de la clase desde el módulo clases.py # Creación de objetos de la clase Partido from clases import Partido partido1 = Partido("Real Madrid", "Atlético", 0, 1) #Objeto partido1 partido2 = Partido("FC Barcelona", "Real Betis", 0, 3) print(partido1.eqLocal) print(partido2.eqVisintante) #La salida es: Real Madrid Real Betis
Atributos de instancia y de clase.
Al trabajar con clases y objetos podemos encontrarnos con dos tipos de atributos: de instancia y de clase. Los atributos de instancia son propios de cada instancia (de cada objeto). Si existen varios objetos de la clase “Empleado”, cada uno de ellos tendrá un valor para el nombre, salario, correo, etc. Sin embargo, los atributos de clase son compartidos por todos los objetos de esa clase.
En el ejemplo siguiente, la clase “Empleado” ha sido modificada añadiendo un atributo de clase llamado “contador”. Este atributo se inicializa con el valor cero, y se
incrementará en uno cada vez que se cree un objeto de esta clase (cada vez que se llame al constructor). Servirá para conocer cuántos objetos de la clase “Empleado” se crean.
#Clase Empleado class Empleado: #Atributo de clase (compartido por todos los objetos que se creen) contador = 0 def __init__(self, nombre, salario, correo, telefono): self.nombre = nombre self.salario = salario self.correo = correo self. telefono = telefono Empleado.contador += 1 #Incrementa el contador de empleados (por cada empleado creado suma 1) def aumentar_salario(self, porcentaje): self.salario = self.salario + self.salario * porcentaje
Para acceder al valor de un atributo de clase desde dentro de la clase se utiliza el nombre de la clase y el nombre del atributo (ver línea 9 del ejemplo). Sin embargo, desde fuera de la clase puede accederse al valor de estos atributos de clase utilizando tanto el nombre de la clase como el nombre de cualquier instancia de la misma. Estudia el siguiente código
from clases import Empleado # Y creamos los objetos empleado1 y empleado2 empleado1 = Empleado("Perico", 6000, "perico@palotes.com", "456987123") empleado2 = Empleado("Armando", 5000, "armando@bronca.com", "789123654") #Acceso al atributo de clase "contador" print(empleado1.contador) #a través de la instancia (objeto) print(Empleado.contador) #a través de la clase
Métodos de instancia y de clase
Los primeros permiten el acceso a los atributos de la instancia. Los métodos de clase, por su parte, proporcionan acceso a los atributos de la clase.
Un método de clase va precedido del decorador “@classmethod” y no puede acceder a los atributos de instancia. Además, recibe la clase de forma implícita como primer argumento.
#Clase Empleado class Empleado: #Atributo de clase (compartido por todos los objetos que se creen) contador = 0 def __init__(self, nombre, salario, correo, telefono): self.nombre = nombre self.salario = salario self.correo = correo self. telefono = telefono Empleado.contador += 1 #Incrementa el contador de empleados (por cada empleado creado suma 1) # Método de instancia def aumentar_salario(self, porcentaje): self.salario = self.salario + self.salario * porcentaje # Método de instancia def datos_empleado(self): return f"Nombre: {self.nombre}, Salario {self.salario}, Correo{self.correo}" # Método de clase @classmethod def mostrar_contador(cls): return f"el número de empleados es: {cls.contador}
Los métodos “aumentar_salario” y “datos_empleado” son métodos de instancia. El primero aumenta el salario de un empleado en el porcentaje pasado como argumento. El segundo método retorna una cadena con nombre, salario y correo del empleado.
El método “mostrar_contador” es un método de clase. Observa cómo lleva el decorador “@classmethod” y el parámetro “cls”, que permite acceder al atributo de clase, “cls.contador.
En esta imagen se crean dos objetos “Empleado” y se llama a los métodos de instancia y clase. Estudia la salida mostrada en el “Terminal”
from clases import Empleado empleado1 = Empleado("Perico", 6000, "perico@palotes.com", "456987123") empleado2 = Empleado("Armando", 5000, "armando@bronca.com", "789123654") #Llamada al método de instancia print(empleado1.datos_empleado()) print(empleado2.datos_empleado()) print() #Llamada al método de clase print(Empleado.mostrar_contador())
Encapsulamiento.
El encapsulamiento es un mecanismo que permite ocultar o limitar el acceso a las propiedades y métodos de un objeto desde el exterior. Este acceso solo estará disponible a través de determinados métodos, con lo que se consigue proteger al objeto frente a posibles cambios no deseados.
En algunos lenguajes de programación este control de acceso se implementa a nivel de clase, mediante modificadores que indican cuando una propiedad o método es público, privado o protegido. Un elemento privado es accesible solo desde dentro de la clase. Sin embargo, si está declarado como público puede ser accedido desde el exterior. Si el atributo o método es protegido significa que es accesible desde dentro de la clase y de las subclases que heredan de esta.
En Python esta posibilidad no existe, todo lo definido en una clase es público por defecto y por tanto accesible desde el exterior. Para conseguir que algún elemento de una clase sea considerado protegido o privado, Python ha adoptado las convenciones siguientes:
- Si el nombre del atributo/método va precedido de un guión bajo (_), se le considera
protegido. - Si el nombre del atributo/método va precedido de un doble guión bajo (__), se le
considera privado.
Será el propio programador el que decidirá si seguir o no estas convenciones. Es necesario mencionar que los atributos siempre son accesibles desde el exterior de esta forma:
- Atributo protegido: objeto._atributo.
- Atributo oculto: objeto._Clase__atributo.
En el ejemplo siguiente, se crea una clase “Persona” con dos atributos, nombre y edad. La edad se define como un atributo privado (doble guión bajo). El acceso a la edad se realiza mediante el método “edad_persona”. Sin embargo, como se indica arriba, puede accederse a la edad mediante “objeto._Clase__atributo”.
#Clase Persona class Persona: def __init__(self, nombre, edad): self.nombre = nombre self.__edad = edad #Atributo privado def edad_persona(self): return self.__edad
from clases import Persona persona1 = Persona("Juan", 30) persona2 = Persona("Maria", 25) #Acceso a los atributos de la clase print(persona1.nombre) # atributo público print(persona1.edad_persona()) # atributo privado, acceso mediante método print(persona1._Persona__edad) # atributo privado, acceso directo print(persona1.__edad) #Genera un excepción AttributeError
Métodos estáticos (@staticmethod).
Puede decirse que un método estático es una función definida a nivel de clase. Está asociado a la clase antes que a los objetos de la misma. Son llamados utilizando el nombre de la clase, y además no pueden alterar el estado de un objeto ni los atributos de clase.
Los métodos estáticos se diferencian de los métodos de clase en que los primeros no operan con los atributos de clase. Se utilizan en alguna de estas situaciones:
- Cuando se quiere implementar una funcionalidad que no depende de ningún atributo de la clase ni de una instancia en particular de la clase.
- Por motivos de organización del código de la aplicación. Puede crearse una clase que contenga una o varias funciones que serán utilizadas en varios puntos de la aplicación.
En Python un método estático se crea con el decorador “@staticmethod”.
En el ejemplo se crea la clase “OperaCadena” que contiene métodos para trabajar con cadenas de caracteres. Los métodos son estáticos (@staticmethod) y son llamados utilizando el nombre de la clase.
# Clase OperaCadena para métodos estáticos class OperaCadena(): @staticmethod def primera_letra(cadena): return cadena[0] @staticmethod def cadena_mayuscula(cadena): return cadena.upper() @staticmethod def cadena_minuscula(cadena): return cadena.lower()
from clases import OperaCadena print(OperaCadena.primera_letra("Hola Mundo")) print(OperaCadena.cadena_mayuscula("Hola Mundo")) print(OperaCadena.cadena_minuscula("Hola Mundo")) #Salida: H HOLA MUNDO hola mundo
Funciones especiales para trabajar con atributos.
Dentro de las funciones definidas de Python (built-in functions) existen varias para trabajar con los atributos o propiedades de un objeto. Estas funciones permiten la “manipulación dinámica de atributos” y son las siguientes:
- getattr(objeto, “atributo”). Retorna el
atributo referenciado de ese objeto. - hasattr(objeto, “atributo”). Retorna un
boolean que indica si el objeto tiene o
no ese atributo. - delattr(objeto, “atributo”). Elimina el atributo del objeto.
- setattr(objeto, “atributo”, valor). Esta función no solo sirve para asignar un valor a un
atributo sino que permite también añadir nuevos atributos a un objeto en tiempo
de ejecución.
from empleados import Empleado empleado3 = Empleado("Pablo", 4500, "pablo@marmol.com", "416987123") #Acceder al nombre del empleado print(getattr(empleado3, "nombre")) # Modidficar el salario del empleado setattr(empleado3, "salario", 60000) print(getattr(empleado3, "salario")) #Comparar si el atributo existe print(hasattr(empleado3, "edad")) #Probar si se elimina el atributo delattr(empleado3, "salario") print(hasattr(empleado3, "salario")) #Salida: Pablo 60000 False False
Métodos mágicos o dunder (double underscore).
Son funciones definidas a nivel de clase, y su nombre comienza y termina con doble guión bajo (__). Aunque pueden ser invocados, suelen ser llamados por Python en situaciones especiales.
class EmpleadoMetodoDunder: def __init__(self, nombre, salario): self.nombre = nombre self.salario = salario def __str__(self): return f"Nombre: {self.nombre}, Salario: {self.salario}" def __eq__(self, otro): return self.salario == otro.salario def __repr__(self): return f"Nombre: {self.__dict__}" def __len__(self): return len(self.nombre)
Autoevalución.- 2.

#Clase Partido class Partido: def __init__(self, eqLocal, eqVisitante, puntosLocal, puntosVisitante):#Entre paréntesis argumentos #Atributos self.eqLocal = eqLocal self.eqVisintante = eqVisitante self.puntosLocal = puntosLocal self.puntosVisitante = puntosVisitante #Añadimos el método def __str__(self): return f"{self.eqLocal} {self.puntosLocal} - {self.eqVisintante} {self.puntosVisitante}"
from clases import Partido partido1 = ("Mortadelo", "Borgoroso", 3, 1) print(partido1) #salida: Mortadelo 3 - Borgoroso 1

#Clase Partido class Partido: contador_partidos = 0 #Defino el atributo de clase contador_partidos def __init__(self, eqLocal, eqVisitante, puntosLocal, puntosVisitante):#Entre paréntesis argumentos #Atributos self.eqLocal = eqLocal self.eqVisintante = eqVisitante self.puntosLocal = puntosLocal self.puntosVisitante = puntosVisitante Partido.contador_partidos += 1 #Incrementa el contador por cada objeto partido creado def __str__(self): return f"{self.eqLocal} {self.puntosLocal} - {self.eqVisintante} {self.puntosVisitante}" #Creamos el método de la clase para mostrar el contador @classmethod def mostrar_contador_partidos(cls): return f"el número de partidos es: {cls.contador_partidos}"
from clases import Partido partido1 = Partido("Real Madrid", "Atlético", 0, 1) partido2 = Partido("FC Barcelona", "Real Betis", 0, 3) partido3 = Partido("Valencia", "Real Betis", 0, 3) print(partido1) print(partido2) print(partido3) print(Partido.mostrar_contador_partidos()) #Salida Real Madrid 0 - Atlético 1 FC Barcelona 0 - Real Betis 3 Valencia 0 - Real Betis 3 el número de partidos es: 3
Continúa –> Métodos mágicos o dunder (double underscore).
from empleadometodosDunder import EmpleadoMetodoDunder emp1 = EmpleadoMetodoDunder("Pedro", 2000) emp2 = EmpleadoMetodoDunder("Pablo", 3000) # llamada a __str__ print(emp2) #llamada a __len__ print(len(emp1)) #llamada a __eq__ print(emp1 == emp2) #llamada a __repr__ print(repr(emp1)) #Salida: Nombre: Pablo, Salario: 3000 5 False Nombre: {'nombre': 'Pedro', 'salario': 2000}
Estudia detenidamente cómo se realiza la llamada en cada caso.
- Llamada al método str().
- Llamada al método len().
- Llamada al método eq().
- Llamada al método repr().
Eliminar objetos. El recolector de basura (Garbage Collector).
Un “recolector de basura” es un proceso que se utiliza para eliminar los objetos que no van a ser utilizados más. En Python, este recolector funciona de forma automática, liberando de ese trabajo al programador.
Cómo eliminar objetos.
La sentencia “del” permite eliminar objetos, elementos de listas y claves de diccionarios que no van a ser necesarios. Sería la operación contraria a la creación del objeto.
Escenarios donde puede ser conveniente usar “del”:
- Liberar memoria.
- Prevenir el uso de variables no existentes.
- Evitar conflictos de nombres.
La sintaxis de esta sentencia sería: “del referencia”. Dónde referencia puede ser un identificador (de variable, clase, función…), un índice o trozo (slice) de una secuencia mutable, una clave de diccionario o un miembro de una clase (atributo u objeto).
En la imagen puedes observar ejemplos del uso de esta sentencia.
a = [1,2,3,4,5,6,7,8,9,10] b = 10 #Eliminar un elmento de una lista del a[2] print(a) #Salida: a = [1,2,3,4,5,6,7,8,9,10] b = 10 #Eliminar una variable del b print(b) #Salida: NameError: name 'b' is not defined
Cuando se intenta hacer uso de un objeto eliminado se obtiene la excepción “NameError”. La sentencia “del” permite eliminar también atributos/métodos de clase y atributos de instancia.
Cómo funciona el recolector de basura
(texto extraído íntegro de Stackoverflow).
Aunque el recolector de basura funciona automáticamente en Python y no debería ser algo de lo que te tengas que preocupar, conocer algunos detalles de cómo Python gestiona la memoria pueden serte útiles (aún sin usar nunca la interfaz gc). En python todos los datos son en realidad objetos y ocupan un espacio en
memoria mayor de lo que cabría esperar en otros lenguajes, debido a que no sólo se guarda el dato en sí, sino también meta-información acerca del mismo (su tipo entre otras cosas).
Por ejemplo, cuando usas un entero en tu programa como aquí, a = 10000, el intérprete necesita reservar un espacio en memoria donde poder guardar un objeto de tipo int que contiene el dato 10000. Lo que ocupe el objeto depende un poco de la implementación de Python con la que estés trabajando. En CPython por ejemplo ocuparía 28 bytes. En otros lenguajes el entero es un dato de 32 bits (o de 64, según la arquitectura) por lo que ocuparía tan sólo 4 bytes (u 8, según la arquitectura).
Una variable no es más que una referencia (un puntero si prefieres llamarlo así) a la dirección de memoria donde está realmente el dato. La memoria que se ha reservado para contener el entero 10000 permanecerá ocupada mientras haya alguna referencia que se refiera a ese dato. Internamente el intérprete mantiene un contador de referencias que va actualizando con cada asignación. Por ejemplo en este momento el contador de referencias sería 1, porque hemos asignado el dato a una variable a, y por tanto hay una referencia 444 apuntando a él. Si seguidamente haces por ejemplo, b = a, Entonces el intérprete creará una variable b y copiará a ella la referencia que había en a, de modo que en este momento hay dos referencias al mismo objeto. Tanto a como b se están refiriendo al mismo objeto. Su contador de referencias vale 2. Si seguidamente haces por ejemplo, a = a + 1 entonces ocurren varias cosas:
● Se crea un nuevo objeto de tipo int para contener el resultado de la operación (otros 28 bytes que son necesarios)
● Se inicializa ese nuevo objeto int con el valor 10001 (qué es el resultado de la operación)
● Se cambia la referencia que había en a (que apuntaba al entero 10000) para que ahora apunte al entero 10001.
● Como consecuencia de esta asignación, el entero 10001 incrementa su contador de referencias que pasa a valer 1 (la referencia a apunta a él) y el entero 10000 decrementa su contador de referencias, ya que ha dejado de apuntar a él. El contador de referencias de 10000 vale 1 (porque b todavía
apunta a él).
Si finalmente haces algo como, b = «Hola», eso creará un nuevo objeto en memoria de tipo str, inicializado con la cadena «Hola», y hará que la referencia b cambie su valor para pasar a apuntar a este objeto. Como consecuencia el objeto str tiene su contador de referencias a 1, y el contador de referencias de 10000 pasa a
cero, pues b ha dejado de apuntar a él. Entonces el intérprete ejecutará el recolector de basura para eliminar los objetos cuyo contador de referencias es 0. En este caso se liberará el objeto int que valía 10000, liberándose así 28 bytes de memoria.
Moralejas de lo anterior:
- Las operaciones son más complicadas de lo que aparentaban en la superficie. Si vienes de un lenguaje como C, te habrá sorprendido el follón que se ha montado para un simple a=a+1. En C lo que ocurría simplemente es que la posición de memoria en que estaba guardado el 10000 se sobreescribe y pasa a contener un 10001. En Python no, pues los enteros son inmutables. Un 10000 siempre será un 10000 (mientras exista)
- La memoria no se va a liberar mientras tengas variables que se refieren a ese objeto. Por tanto una posible forma de liberar memoria cuando andes escaso de ella puede ser borrar la referencia.
La instrucción “del a”, por ejemplo, elimina la referencia llamada a, decrementando así el contador de referencias del objeto al que apuntaba.
Considera este ejemplo:
a = 10000
del a
a Traceback (most recent call last): File «», line 1, in
NameError: name ‘a’ is not defined
La primera instrucción reservará 28 bytes para el entero 10000 y la
referencia a apuntará a ese entero. Su contador de referencias será por tanto 1. La línea del a elimina la variable a (que pasa a ser no definida como se comprueba seguidamente). El entero al que “a” apuntaba pasará a tener un contador de referencias cero, y será por tanto liberado por el recolector de basura.
Es necesario mencionar que el recolector de basura de Python no actúa inmediatamente, tras eliminar la última referencia de un objeto. El procedimiento usado es el de escanear la memoria de forma periódica buscando objetos no referenciados.
Es necesario mencionar que el recolector de basura de Python no actúa inmediatamente, tras eliminar la última referencia de un objeto. El procedimiento usado es el de escanear la memoria de forma periódica buscando objetos no referenciados.
La palabra reservada “pass”.
La palabra “pass” se utiliza como “placeholder” para un futuro código. Su ejecución no tiene consecuencias y se utiliza para evitar errores cuando no disponemos del código asociado a una función, clase, bucle o sentencia condicional.
# Método abstracto from abc import abstractmethod @abstractmethod def get_info(self) pass
Atributos dinámicos
Python permite alterar el número de atributos de un objeto de forma dinámica, tanto dentro como fuera de la definición de la clase. Este cambio en el número de atributos implica tanto la eliminación (como se vio en el apartado 8) como la adición de atributos nuevos.
Para añadir un atributo nuevo a un objeto basta con utilizar la sintaxis “objeto.atributo = valor”. Llegados a este punto, para conocer todos los atributos de un objeto puede usarse el atributo dict que posee todo objeto. Este atributo contiene un diccionario con las parejas nombre de atributo y valor.
Cómo saber si dos objetos son iguales
Escenario 1. Partimos de dos referencias y queremos determinar si apuntan a la misma dirección de memoria.
Para ello hacemos uso de los operadores “is” y “not is” que determinan si dos referencias apuntan a la misma dirección de memoria.
En este caso, a y b apuntan al mismo dato. La pregunta “a is b” retorna True.
El método id(objeto) retorna un identificador único del objeto almacenado en memoria.
# Comparamos dos objetos si son iguales a = 10 b = a print (a is b) print (id(a)) print (id(b)) #Salida True 140717919765704 140717919765704
Escenario 2. Partimos de dos objetos y queremos determinar si sus atributos son iguales. En este caso, debemos definir el método eq en la clase y dentro de él comparar por parejas los atributos de ambos objetos. Este método retorna True en caso de que todas las comparaciones sean True.
#Clase Persona class Persona: def __init__(self, nombre, edad): self.nombre = nombre self.__edad = edad #Atributo privado def edad_persona(self): return self.__edad def __str__(self): return f'Persona: {self.nombre} + {self.__edad}' def __eq__(self, value): return self.nombre == value.nombre \ and self.__edad == value.__edad from clases import Persona x = Persona("Juan", 25) y = Persona("Juan", 25) print(x is y) print(x == y) #Salida: False True
Observa como el operador “is” retorna False y la comparación mediante “==” retorna True. Son objetos distintos pero guardan los mismos valores en sus atributos.