| You are here: Inicio > Inmersión en Python > Objetos y orientación a objetos > Definición de clases | << >> | ||||
Inmersión en PythonPython de novato a experto |
|||||
Python está completamente orientado a objetos: puede definir sus propias clases, heredar de las que usted defina o de las incorporadas en el lenguaje, e instanciar las clases que haya definido.
Definir una clase en Python es simple. Como con las funciones, no hay una definición interfaz separada. Simplemente defina la clase y empiece a escribir código. Una clase de Python empieza con la palabra reservada class, seguida de su nombre. Técnicamente, esto es todo lo que necesita, ya que la clase no tiene por qué heredar de ninguna otra.
class Loaf:pass
![]()
| La sentencia pass de Python es como unas llaves vacías ({}) en Java o C. | |
Por supuesto, siendo realistas, la mayoría de las clases heredarán de alguna otra, y definirán sus propios métodos y atributos. Pero como acabamos de ver, no hay nada que una clase deba tener, aparte de su nombre. En particular, los programadores de C++ encontrarán extraño que las clases de Python no tengan constructores o destructores explícitos. Las clases de Python tienen algo similar a un constructor: el método __init__.
from UserDict import UserDict class FileInfo(UserDict):
| En Python, el ancestro de una clase se lista simplemente entre paréntesis inmediatamente del nombre de la clase. Así que la clase FileInfo hereda de la clase UserDict (que importamos del módulo UserDict). UserDict es una clase que actúa como un diccionario, permitiéndole derivar el tipo de datos diccionario y añadir comportamientos a su gusto (existen las clases similares UserList y UserString que le permiten derivar listas y cadenas). Hay un poco de magia negra tras todo esto, que demistificaré más adelante en este capítulo cuando exploremos la clase UserDict en más profundidad. |
| En Python, el ancestro de una clase se lista entre paréntesis inmediatamente tras el nombre de la clase. No hay palabras reservadas especiales como extends en Java. | |
Python admite herencia múltiple. En los paréntesis que siguen al nombre de la clase, puede enumerar tantas clases ancestro como desee, separadas por comas.
Este ejemplo muestra la inicialización de la clase FileInfo usando el método __init__.
class FileInfo(UserDict): "store file metadata"def __init__(self, filename=None):
![]()
![]()
| Las clases pueden también (y deberían) tener cadenas de documentación, al igual que los módulos y funciones. | |
| __init__ se llama inmediatamente tras crear una instancia de la clase. Sería tentador pero incorrecto denominar a esto el constructor de la clase. Es tentador porque parece igual a un constructor (por convención, __init__ es el primer método definido para la clase), actúa como uno (es el primer pedazo de código que se ejecuta en una instancia de la clase recién creada), e incluso suena como una (“init” ciertamente sugiere una naturaleza constructórica). Incorrecto, porque el objeto ya ha sido construido para cuando se llama a __init__, y ya tiene una referencia válida a la nueva instancia de la clase. Pero __init__ es lo más parecido a un constructor que va a encotnrar en Python, y cumple el mismo papel. | |
| El primer método de cada método de clase, incluido __init__, es siempre una referencia a la instancia actual de la clase. Por convención, este argumento siempre se denomina self. En el método __init__, self se refiere al objeto recién creado; en otros métodos de la clase, se refiere a la instancia cuyo método ha sido llamado. Aunque necesita especificar self de forma explícita cuando define el método, no se especifica al invocar el método; Python lo añadirá de forma automática. | |
| Los métodos __init__ pueden tomar cualquier cantidad de argumentos, e igual que las funciones, éstos pueden definirse con valores por defecto, haciéndoles opcionales para quien invoca. En este caso, filename tiene el valor por omisión de None, que es el valor nulo de Python. |
| Por convención, el primer argumento de cualquier clase de Python (la referencia a la instancia) se denomina self. Este argumento cumple el papel de la palabra reservada this en C++ o Java, pero self no es una palabra reservada en Python, sino una mera convención. De todas maneras, por favor no use otro nombre sino self; es una convención muy extendida. | |
class FileInfo(UserDict): "store file metadata" def __init__(self, filename=None): UserDict.__init__(self)self["name"] = filename
![]()
Cuando defina los métodos de su clase, debe enumerar self de forma explícita como el primer argumento de cada método, incluido __init__. Cuando llame a un método de una clase ancestra desde dentro de la clase, debe incluir el argumento self. Pero cuando invoque al método de su clase desde fuera, no debe especificar nada para el argumento self; evítelo completamente, y Python añadirá automáticamente la referencia a la instancia. Soy consciente de que esto es confuso al principio; no es realmente inconsistente, pero puede parecer inconsistente debido a que se basa en una distinción (entre métodos bound y unbound) que aún no conoce.
¡Vaya! Me doy cuenta de que es mucho por absorber, pero le acabará pillando el truco. Todas las clases de Python funcionan de la misma manera, de manera que cuando aprenda una, las habrá aprendido todas. Si se olvida de algo, recuerde esto, porque prometo que se lo tropezará:
| Los métodos __init__ son opcionales, pero cuando define uno, debe recordar llamar explícitamente al método __init__ del ancestro (si define uno). Suele ocurrir que siempre que un descendiente quiera extender el comportamiento de un ancestro, el método descendiente deba llamar al del ancestro en el momento adecuado, con los argumentos adecuados. | |
<< Importar módulos usando from módulo import |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
Instanciación de clases >> |