Clases y Objetos
Python es un lenguaje orientado a objetos, luego la manera más útil de programar en python, es usar este paradigma.
Terminología
Lo primero se debe de tener claro, es a que nos referimos cuando hablamos de , clase, objeto, herencia ...
- Clases: Es el prototipo de un objeto, con la definición sus atributos y métodos.
- Atributos: Son el conjunto de variables definidas para una clase de objetos (internos).
- Métodos: Son el conjunto de funciones definidas para una clase de objetos (internos)
- Miembros de la Clase: Son tanto los métodos como los atributos.
- Herencia: La transferencia de características de una clase a otra derivada de ella
- Instancia: Se llama instancia un objeto creado a partir de una clase.
- Instanciación: La creación de un objeto.
- Objeto: Una estructura única que es definida por su clase, un objeto es el conjunto de atributos y métodos.
- Operador sobrecargado: Cuando se le asigna a un operador mas de una función.
Creando Clases
Para crear una clase, se utiliza la palabra reservada class, seguida del nombre de la clase y al final dos puntos(como todo en python)
Sintaxis:class Nombre_Clase:
'Documentación de la clase, tal cual las funciones'
Componentes_de_la_clase
- Ejemplo:
class Estudiante:
'Cosas comunes a todo estudiante'
Numero_Estudiantes = 0
def __init__(self, nombre, nivel):
self.nombre = nombre
self.nivel = nivel
Estudiante.Numero_Estudiantes += 1
def display_NE(self):
print ('Numero de estudiantes:', self.Numero_Estudiantes)
def display_Estudiante(self):
print ('Nombre:', self.nombre, ", Nivel: ", self.nivel)
En ésta clase se pueden ver ejemplos de atributos (Numero_Estudiantes, nombre, nivel), de variables de clase (Numero_Estudiantes) que son compartidas por todas las instancias de la clase, y de atributos de la clase (init, display_NE,display_Estudiante).
NOTAS:
- El método __init__ es especial llamado método constructor, y tiene como función la iniciación de los objetos, pertenecientes a la clase.
- Todas los métodos deben de ser creados con una variable self como primera entrada, ésta variable no se usa cuando se llaman dichos métodos.
Instanciando un Objeto
Para crear una instancia de una clase#Creemos el primer objeto estudiante, llamado Camilo en el nivel 10.
estu1=Estudiante("Camilo",10)
#Esto instancia un segundo objeto estudiante, llamado Alfredo en el nivel 1.
estu2=Estudiante("Alfredo",1)
Utilizando Atributos
Se puede acceder a los atributos de los objetos de una clase, a través del operador punto "."
- Ejemplo:
class Estudiante:
'Cosas comunes a todo estudiante'
Numero_Estudiantes = 0
def __init__(self, nombre, nivel):
self.nombre = nombre
self.nivel = nivel
Estudiante.Numero_Estudiantes += 1
def display_NE(self):
print ('Numero de estudiantes:', self.Numero_Estudiantes)
def display_Estudiante(self):
print ('Nombre:', self.nombre, ", Nivel: ", self.nivel)
#Creemos el primer objeto estudiante, llamado Camilo en el nivel 10.
estu1=Estudiante("Camilo",10)
#Esto instancia un segundo objeto estudiante, llamado Alfredo en el nivel 1.
estu2=Estudiante("Alfredo",1)
print("Número de estudiantes: ", estu1.Numero_Estudiantes)
print("Número de estudiantes: ", estu2.Numero_Estudiantes)
estu1.display_Estudiante()
estu2.display_Estudiante()
estu1.display_NE()
estu2.display_NE()
Atributos por defecto
Cada clase que se crea en python tiene los siguientes atributos
- __name__ : Contiene el nombre de la clase
- __module__ : Contiene el nombre del módulo del cual la clase fue cargada, si el valor es text main , es porque se está corriendo desde el modo interactivo.
- __doc__ : Documentación.
- __bases__ : Una tupla que contiene(si hay) en orden de ocurrencia, las clases de las cuales hereda.
- __dict__ : Diccionario, que contiene el espacio de nombres de la clase.
- Ejemplo:
print ("Employee.__doc__:", Employee.__doc__)
print ("Estudiante.__name__:", estu1.__name__)
print ("Estudiante.__module__:", estu1.__module__)
print ("Estudiante.__bases__:", estu1.__bases__)
print ("Estudiante.__dict__:", estu1.__dict__ )
print ("Estudiante.__dict__:", estu2.__dict__ )
Destruyendo Objetos
Python tiene un proceso llamado "Grabage Collection", y lo que hace es borrar los objetos automáticamente para liberar memoria. Este colector de basura se ejecuta mientras el programa corre, y es alertado cuando el contador de referencia de un objeto llega a cero.
El contador de referencia de un objeto, incrementa cuando se le asigna un nuevo nombre, o se pone dentro de un contenedor (tupla, lista, diccionario u otro objeto). El contador de referencia disminuye cuando el objeto es borrado, o cuando se reasigna la referencia a otro elemento o sale de alcance.
- Ejemplo:
a = 40 # Se crea un objeto <40>
b = a # Aumenta el contador de referencia <40>
c = [b] # Aumenta el contador de referencia <40>
del a # Disminuye el contador de referencia <40>
b = 100 # Disminuye el contador de referencia <40>
c[0] = -1 # Disminuye el contador de referencia <40>
Es recomendable no dejar al garbage collector la liberación de la memoria de los objetos creados, lo que se suele hacer es adicionar un método __del__() con el fin de que sea el encargado de eliminar el objeto.
- Ejemplo:
class Punto:
def __init( self, x=0, y=0):
self.x = x
self.y = y
def __del__(self):
class_name = self.__class__.__name__
print (class_name, "destruido")
pt1 = Punto()
pt2 = pt1
pt3 = pt1
print (id(pt1), id(pt2), id(pt3)) # Ésto imprime las referencias
del pt1
del pt2
del pt3
Herencia
Una de las características mas relevantes de la orientación a objetos, es la capacidad de reutilizar código usando la herencia, ésto se hace listando las clases de las que va a heredar en paréntesis luego del nombre y antes de los dos puntos.
Sintaxis:class Nombre_clase_hija (Clase_madre1[, Clase_madre2, ...]):
'Documentaciión'
Cuerpo_Sub_Clase
- Ejemplo:
class Padre: # Clase Padre
def mi_Metodo(self):
print ('Llamada al método mi_Metodo del padre')
class Hijo(Padre): # Clase hija
def mi_Metodo(self):
print ('Llamada al método mi_Metodo del hijo')
p=Padre
h=Hijo
p.mi_Metodo(p)
h.mi_Metodo(h)
Sobrecarga de Operadores y Métodos
Cuando adquirimos la habilidad de crear nuestros propios objetos, bien sea desde cero o con herencia, hay que tener en cuenta que posiblemente muchos de los operadores y métodos que estamos acostumbrados a usar, pueden no funcionar bien sobre nuestros nuevos objetos.
Métodos de base que se pueden sobre cargados.
Los métodos a continuación son métodos que existen en todas las clases de python por defecto, y pueden ser sobrecargados.
- __init__ ( self [,args...] ) : Es el método constructor, y es lo primero que se ejecuta al instanciar una clase.
- __del__( self ) : El método destructor, y siempre se ejecuta cuando se borra un objeto, o cuando es colectado por el garbage colector.
- __cmp__( self ) : El método para comparar dos objetos.
Sobrecarga de Operadores
Cuando se definen nuevos objetos, es normal que uno quiera utilizar los operadores que tienen una interpretación natural.
Algunos de los operadores que podemos sobrecargar son la suma (+), la resta (-), multiplicación (*)
- __add__(self, other) : Suma
- __sub__(self, other) : Resta
- __mul__(self, other) : Multiplicación.
- __getitem__(self,index) : operador [].
- __eq__(self, other) : operador ==.
- __ne__(self, other) : operador !=.
- __lt__(self, other) : operador < .
- __gt__(self, other) : operador > .
- Ejemplo:
class Vector:
'''Es una clase vector de ejemplo'''
def __init__(self, x0=0,y0=0,z0=0):
self.x=x0
self.y=y0
self.z=z0
def __add__(self,other):
return Vector(self.x + other.x, self.y + other.y, self.z + other.z)
def __sub__(self,other):
return Vector(self.x - other.x, self.y - other.y, self.z - other.z)
|