From 353167f50d9a3c5d7336d09d4b0445b5eba233c3 Mon Sep 17 00:00:00 2001 From: Ekaitz Zarraga Date: Sun, 1 Dec 2019 13:07:36 +0100 Subject: Protocols --- src/05_oop.md | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 77 insertions(+), 6 deletions(-) (limited to 'src/05_oop.md') diff --git a/src/05_oop.md b/src/05_oop.md index 2f59066..8a86c50 100644 --- a/src/05_oop.md +++ b/src/05_oop.md @@ -450,20 +450,89 @@ class Clase( SuperClase ): ``` > NOTA: `super` busca la clase previa por preferencia, si usas herencias -> múltiples y pisas los campos puede complicarse. No se trata en este documento -> porque es un caso muy concreto. - - -## Interfaces estándar +> múltiples y pisas los campos puede complicarse. + + +## Interfaces estándar: protocolos + +Una de las razones principales para usar programación orientada a objetos es +que, si se eligen los métodos con precisión, pueden crearse estructuras de +datos que se comporten de similar forma pero que tengan cualidades diferentes. +Independientemente de cómo estén definidas sus clases, si dos objetos disponen +de los mismos métodos podrán ser sustituidos el uno por el otro en el programa +y seguirá funcionando aunque su funcionalidad cambie. + +Dicho de otra forma, dos objetos (o dos cosas, en general) podrán ser +intercambiados si disponen de la misma *interfaz*. *Interfaz*, de *inter*: +entre; y *faz*: cara, viene a significar algo así como «superficie de contacto» +y es la palabra que se usa principalmente para definir la frontera compartida +entre dos componentes o, centrándonos en el caso que nos ocupa, su conexión +funcional. + +Si recuerdas la *herencia* y la combinas con estos conceptos, puedes +interpretar que además de una metodología para reutilizar código es una forma +de crear nuevas definiciones que soporten la misma interfaz. + +En otros lenguajes de programación, Java, por ejemplo, existe el concepto +*interfaz* que serían una especie pequeñas clases que definen qué funciones +debe cumplir una clase para que cumpla la interfaz. A la hora de crear las +clases se les puede indicar qué interfaces implementan y el lenguaje se encarga +de asegurarse de que el programador ha hecho todo como debe. + +El dinamismo de python hace que esto sea mucho más flexible. Debido a que +python no hace casi comprobaciones antes de ejecutarse, necesita un método para +mucho más directo. Para python, *si anda como un pato, vuela como un pato y +nada como un pato: es un pato*. + +Python usa lo que en la terminología del lenguaje se conoce como +*protocolos*[^protocol] (*protocol*) para que los objetos creados por el +programador puedan comportarse como los que el propio sistema aporta. Por +ejemplo, que sea posible utilizarlos como iterable en un `for`, que el sistema +pueda cerrarlos de forma automática, buscar en ellos usando el operador `in`, +etc. Simplemente, el sistema define qué funciones se deben cumplir en cada uno +de esos casos y cuando se encuentre con ellos intentará llamarlas +automáticamente. Si el elemento no dispone de esas funciones lanzará una +excepción como la que lanza cuando intentamos acceder a un método que no existe +(que es básicamente lo que estamos haciendo en este caso). + +En general, python, con el fin de diferenciar claramente qué nombres elige el +programador y cuales han sido seleccionados por el lenguaje, suele utilizar una +convención para la nomenclatura: comienzan y terminan por: `__`. + +A continuación se describen algunos de los protocolos más comunes, algunos ya +han aparecido a lo largo de los ejemplos del documento, otros las verás por +primera vez ahora. Existen muchos más, y todos están extremadamente bien +documentados. Si en algún momento necesitas crear algunos nuevos, la +documentación de python es una buena fuente donde empezar. + +Todos las protocolos se presentan con un nombre, en muchos casos inventado, +terminado en *-able*. Python utiliza también este tipo de nombres, como el ya +aparecido *llamable*, o *callable* en inglés, que se refiere a cualquier cosa +que puede ser llamada. Representar los nombres de esta manera sirve para +expresar el interés de los protocolos. Si en algún momento necesitas crear una +clase que defina un objeto en el que se puede buscar necesitas que sea un +*buscable*, es decir, que soporte el protocolo que define ese comportamiento. + +[^protocol]: **Protocolo**: 5. m. Inform. Conjunto de reglas que se establecen + en el proceso de comunicación entre dos sistemas. — RAE [Consultado + 01-12-2019]: + +### *Representables*: `__repr__` + +### *Contables*: `__len__` + +### *Buscable*: `__contains__` ### *Creables*: `__init__` ### *Iterables*: `__next__` e `__iter__` -### *Abribles* y *cerrables* +### *Abribles* y *cerrables*: `__enter__` y `__exit__` Que funcionen con el `with` +> context management protocol + ### *Llamables*: `__call__` Queda pendiente desde el capítulo sobre funciones, responder a lo que es un @@ -471,6 +540,8 @@ Queda pendiente desde el capítulo sobre funciones, responder a lo que es un https://stackoverflow.com/questions/111234/what-is-a-callable +### *Accesibles*: `__getitem__` y `__setitem__` + ## Lo que has aprendido -- cgit v1.2.3