Python - Orientado a Objetos
Página anteriorPágina siguiente
Python ha sido un lenguaje orientado a objetos desde que existió. Debido a esto, crear y usar clases y objetos es francamente fácil. Este capítulo lo ayuda a convertirse en un experto en el uso del soporte de programación orientada a objetos de Python.
Si no tiene ninguna experiencia previa con la programación orientada a objetos (OO), puede consultar un curso introductorio o al menos un tutorial de algún tipo para que comprenda los conceptos básicos.
Sin embargo, aquí hay una pequeña introducción de la Programación Orientada a Objetos (POO) para llevarlo a la velocidad −
Descripción general de la terminología de programación orientada a objetos
-
Clase − Un prototipo definido por el usuario para un objeto que define un conjunto de atributos que caracterizan cualquier objeto de la clase. Los atributos son miembros de datos (variables de clase y variables de instancia) y métodos, a los que se accede mediante notación de puntos.
-
Variable de clase − Una variable que es compartida por todas las instancias de una clase. Las variables de clase se definen dentro de una clase pero fuera de cualquiera de los métodos de la clase. Las variables de clase no se usan con tanta frecuencia como las variables de instancia.
-
Miembro de datos − Una variable de clase o variable de instancia que contiene datos asociados con una clase y sus objetos.
-
Sobrecarga de funciones − La asignación de más de un comportamiento a una determinada función. La operación realizada varía según los tipos de objetos o argumentos involucrados.
-
Variable de instancia − Una variable que se define dentro de un método y pertenece solo a la instancia actual de una clase.
-
Herencia − La transferencia de las características de una clase a otras clases que se derivan de ella.
-
Instancia − Un objeto individual de cierta clase. Un objeto obj que pertenece a una clase Circle, por ejemplo, es una instancia de la clase Circle.
-
Instanciación − La creación de una instancia de una clase.
-
Método − Un tipo especial de función que se define en una definición de clase.
-
Objeto − Una instancia única de una estructura de datos que está definida por su clase. Un objeto comprende tanto miembros de datos (variables de clase y variables de instancia) como métodos.
-
Sobrecarga de operadores − La asignación de más de una función a un operador en particular.
Creación de clases
La clase declaración crea una nueva definición de clase. El nombre de la clase sigue inmediatamente a la palabra clave clase seguido de dos puntos de la siguiente manera −
class ClassName: 'Optional class documentation string' class_suite
-
La clase tiene una cadena de documentación, a la que se puede acceder a través de ClassName.__doc__ .
-
El class_suite consta de todas las declaraciones de los componentes que definen los miembros de la clase, los atributos de datos y las funciones.
Ejemplo
A continuación se muestra el ejemplo de una clase de Python simple −
class Employee: 'Common base class for all employees' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary
-
La variable empCount es una variable de clase cuyo valor se comparte entre todas las instancias de esta clase. Se puede acceder a esto como Employee.empCount desde dentro de la clase o fuera de la clase.
-
El primer método __init__() es un método especial, que se llama constructor de clase o método de inicialización que llama Python cuando crea una nueva instancia de esta clase.
-
Declaras otros métodos de clase como funciones normales con la excepción de que el primer argumento de cada método es self . Python agrega el yo argumento a la lista para usted; no necesita incluirlo cuando llame a los métodos.
Creación de objetos de instancia
Para crear instancias de una clase, llame a la clase usando el nombre de la clase y pase cualquier argumento que sea __init__ el método acepta.
"This would create first object of Employee class" emp1 = Employee("Zara", 2000) "This would create second object of Employee class" emp2 = Employee("Manni", 5000)
Acceso a atributos
Accede a los atributos del objeto usando el operador de punto con objeto. Se accedería a la variable de clase usando el nombre de clase de la siguiente manera −
emp1.displayEmployee() emp2.displayEmployee() print "Total Employee %d" % Employee.empCount
Ahora, juntando todos los conceptos −
Demostración en vivo#!/usr/bin/python class Employee: 'Common base class for all employees' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary "This would create first object of Employee class" emp1 = Employee("Zara", 2000) "This would create second object of Employee class" emp2 = Employee("Manni", 5000) emp1.displayEmployee() emp2.displayEmployee() print "Total Employee %d" % Employee.empCount
Cuando se ejecuta el código anterior, produce el siguiente resultado −
Name : Zara ,Salary: 2000 Name : Manni ,Salary: 5000 Total Employee 2
Puede agregar, eliminar o modificar atributos de clases y objetos en cualquier momento −
emp1.age = 7 # Add an 'age' attribute. emp1.age = 8 # Modify 'age' attribute. del emp1.age # Delete 'age' attribute.
En lugar de usar las declaraciones normales para acceder a los atributos, puede usar las siguientes funciones −
-
El getattr(obj, nombre[, predeterminado]) − para acceder al atributo del objeto.
-
El hasattr(obj,nombre) − para comprobar si un atributo existe o no.
-
El setattr(obj,nombre,valor) − para establecer un atributo. Si el atributo no existe, entonces se crearía.
-
El delattr(obj, nombre) − para borrar un atributo.
hasattr(emp1, 'age') # Returns true if 'age' attribute exists getattr(emp1, 'age') # Returns value of 'age' attribute setattr(emp1, 'age', 8) # Set attribute 'age' at 8 delattr(empl, 'age') # Delete attribute 'age'
Atributos de clase incorporados
Cada clase de Python sigue los atributos incorporados y se puede acceder a ellos usando el operador de punto como cualquier otro atributo −
-
__dict__ − Diccionario que contiene el espacio de nombres de la clase.
-
__doc__ − Cadena de documentación de clase o ninguna, si no está definida.
-
__nombre__ − Nombre de la clase.
-
__módulo__ − Nombre del módulo en el que se define la clase. Este atributo es "__main__" en modo interactivo.
-
__base__ − Una tupla posiblemente vacía que contiene las clases base, en el orden en que aparecen en la lista de clases base.
Para la clase anterior, intentemos acceder a todos estos atributos −
Demostración en vivo#!/usr/bin/python class Employee: 'Common base class for all employees' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary print "Employee.__doc__:", Employee.__doc__ print "Employee.__name__:", Employee.__name__ print "Employee.__module__:", Employee.__module__ print "Employee.__bases__:", Employee.__bases__ print "Employee.__dict__:", Employee.__dict__
Cuando se ejecuta el código anterior, produce el siguiente resultado −
Employee.__doc__: Common base class for all employees Employee.__name__: Employee Employee.__module__: __main__ Employee.__bases__: () Employee.__dict__: {'__module__': '__main__', 'displayCount': <function displayCount at 0xb7c84994>, 'empCount': 2, 'displayEmployee': <function displayEmployee at 0xb7c8441c>, '__doc__': 'Common base class for all employees', '__init__': <function __init__ at 0xb7c846bc>}
Destrucción de objetos (recolección de basura)
Python elimina objetos innecesarios (tipos incorporados o instancias de clase) automáticamente para liberar espacio en la memoria. El proceso mediante el cual Python recupera periódicamente bloques de memoria que ya no están en uso se denomina Recolección de basura.
El recolector de basura de Python se ejecuta durante la ejecución del programa y se activa cuando el recuento de referencias de un objeto llega a cero. El número de referencias de un objeto cambia a medida que cambia el número de alias que apuntan a él.
El recuento de referencias de un objeto aumenta cuando se le asigna un nuevo nombre o se coloca en un contenedor (lista, tupla o diccionario). El recuento de referencias del objeto disminuye cuando se elimina con del , su referencia se reasigna o su referencia queda fuera del ámbito. Cuando el recuento de referencias de un objeto llega a cero, Python lo recopila automáticamente.
a = 40 # Create object <40> b = a # Increase ref. count of <40> c = [b] # Increase ref. count of <40> del a # Decrease ref. count of <40> b = 100 # Decrease ref. count of <40> c[0] = -1 # Decrease ref. count of <40>
Normalmente no se dará cuenta cuando el recolector de elementos no utilizados destruya una instancia huérfana y recupere su espacio. Pero una clase puede implementar el método especial __del__() , llamado destructor, que se invoca cuando la instancia está a punto de ser destruida. Este método podría utilizarse para limpiar cualquier recurso que no sea de memoria utilizado por una instancia.
Ejemplo
Este destructor __del__() imprime el nombre de clase de una instancia que está a punto de ser destruida −
Demostración en vivo#!/usr/bin/python class Point: def __init__( self, x=0, y=0): self.x = x self.y = y def __del__(self): class_name = self.__class__.__name__ print class_name, "destroyed" pt1 = Point() pt2 = pt1 pt3 = pt1 print id(pt1), id(pt2), id(pt3) # prints the ids of the obejcts del pt1 del pt2 del pt3
Cuando se ejecuta el código anterior, produce el siguiente resultado −
3083401324 3083401324 3083401324 Point destroyed
Nota − Idealmente, debe definir sus clases en un archivo separado, luego debe importarlas en su archivo de programa principal usando importar declaración.
Herencia de clase
En lugar de comenzar desde cero, puede crear una clase derivándola de una clase preexistente enumerando la clase principal entre paréntesis después del nuevo nombre de clase.
La clase secundaria hereda los atributos de su clase principal y puede usar esos atributos como si estuvieran definidos en la clase secundaria. Una clase secundaria también puede anular los miembros de datos y los métodos de la clase principal.
Sintaxis
Las clases derivadas se declaran como su clase principal; sin embargo, se proporciona una lista de clases base para heredar después del nombre de la clase −
class SubClassName (ParentClass1[, ParentClass2, ...]): 'Optional class documentation string' class_suite
Ejemplo
Demostración en vivo#!/usr/bin/python class Parent: # define parent class parentAttr = 100 def __init__(self): print "Calling parent constructor" def parentMethod(self): print 'Calling parent method' def setAttr(self, attr): Parent.parentAttr = attr def getAttr(self): print "Parent attribute :", Parent.parentAttr class Child(Parent): # define child class def __init__(self): print "Calling child constructor" def childMethod(self): print 'Calling child method' c = Child() # instance of child c.childMethod() # child calls its method c.parentMethod() # calls parent's method c.setAttr(200) # again call parent's method c.getAttr() # again call parent's method
Cuando se ejecuta el código anterior, produce el siguiente resultado −
Calling child constructor Calling child method Calling parent method Parent attribute : 200
De manera similar, puede conducir una clase desde varias clases principales de la siguiente manera −
class A: # define your class A ..... class B: # define your class B ..... class C(A, B): # subclass of A and B .....
Puede usar las funciones issubclass() o isinstance() para verificar las relaciones de dos clases e instancias.
-
La essubclase(sub, sup) La función booleana devuelve verdadero si la subclase dada sub es de hecho una subclase de la superclase sup .
-
La esunainstancia(obj, Clase) La función booleana devuelve verdadero si obj es una instancia de la clase Clase o es una instancia de una subclase de Class
Métodos anulados
Siempre puede anular los métodos de su clase principal. Una de las razones para anular los métodos de los padres es que es posible que desee una funcionalidad especial o diferente en su subclase.
Ejemplo
Demostración en vivo#!/usr/bin/python class Parent: # define parent class def myMethod(self): print 'Calling parent method' class Child(Parent): # define child class def myMethod(self): print 'Calling child method' c = Child() # instance of child c.myMethod() # child calls overridden method
Cuando se ejecuta el código anterior, produce el siguiente resultado −
Calling child method
Métodos de sobrecarga de bases
La siguiente tabla enumera algunas funciones genéricas que puede anular en sus propias clases −
Sr.No. | Método, descripción y llamada de muestra |
---|---|
1 | __init__ (auto [,argumentos...]) Constructor (con cualquier argumento opcional) Ejemplo de llamada:obj =className(args) |
2 | __del__(uno mismo) Destructor, borra un objeto Ejemplo de llamada:del obj |
3 | __repr__(uno mismo) Representación de cadenas evaluables Ejemplo de llamada:repr(obj) |
4 | __str__(uno mismo) Representación de cadena imprimible Ejemplo de llamada:str(obj) |
5 | __cmp__ (uno mismo, x) Comparación de objetos Ejemplo de llamada:cmp(obj, x) |
Operadores de sobrecarga
Supongamos que ha creado una clase Vector para representar vectores bidimensionales, ¿qué sucede cuando usa el operador más para agregarlos? Lo más probable es que Python te grite.
Sin embargo, podría definir el __add__ método en su clase para realizar la suma de vectores y luego el operador más se comportaría según las expectativas −
Ejemplo
Demostración en vivo#!/usr/bin/python class Vector: def __init__(self, a, b): self.a = a self.b = b def __str__(self): return 'Vector (%d, %d)' % (self.a, self.b) def __add__(self,other): return Vector(self.a + other.a, self.b + other.b) v1 = Vector(2,10) v2 = Vector(5,-2) print v1 + v2
Cuando se ejecuta el código anterior, produce el siguiente resultado −
Vector(7,8)
Ocultación de datos
Los atributos de un objeto pueden o no ser visibles fuera de la definición de clase. Debe nombrar los atributos con un prefijo de subrayado doble, y esos atributos no serán visibles directamente para los extraños.
Ejemplo
Demostración en vivo#!/usr/bin/python class JustCounter: __secretCount = 0 def count(self): self.__secretCount += 1 print self.__secretCount counter = JustCounter() counter.count() counter.count() print counter.__secretCount
Cuando se ejecuta el código anterior, produce el siguiente resultado −
1 2 Traceback (most recent call last): File "test.py", line 12, in <module> print counter.__secretCount AttributeError: JustCounter instance has no attribute '__secretCount'
Python protege a esos miembros cambiando internamente el nombre para incluir el nombre de la clase. Puede acceder a atributos como object._className__attrName . Si reemplazara su última línea de la siguiente manera, entonces funciona para usted −
......................... print counter._JustCounter__secretCount
Cuando se ejecuta el código anterior, produce el siguiente resultado −
1 2 2
python
- Clase y objeto de C#
- Tipos de datos de Python
- Operadores de Python
- Declaración de paso de Python
- Diccionario de Python
- Excepciones personalizadas de Python
- Programación orientada a objetos de Python
- Herencia de Python
- Clase única de Java
- Seguimiento automático de objetos por visión
- type() y isinstance() en Python con ejemplos