summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEkaitz Zarraga <ekaitz@elenq.tech>2019-12-01 13:07:36 +0100
committerEkaitz Zarraga <ekaitz@elenq.tech>2019-12-01 13:07:36 +0100
commit353167f50d9a3c5d7336d09d4b0445b5eba233c3 (patch)
treeeda40caea20890c27a55886b7610c0b3b8d7c234
parent452b0e0403f56eede5a61555d3b70c13b6b06275 (diff)
Protocols
-rw-r--r--src/05_oop.md83
1 files changed, 77 insertions, 6 deletions
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]: <https://dle.rae.es/protocolo>
+
+### *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