summaryrefslogtreecommitdiff
path: root/src/05_oop.md
diff options
context:
space:
mode:
authorEkaitz Zarraga <ekaitz@elenq.tech>2019-12-01 16:38:18 +0100
committerEkaitz Zarraga <ekaitz@elenq.tech>2019-12-01 16:38:18 +0100
commitfb47609021e2a8890559862032c0b54c30b05829 (patch)
tree90431363629af2d9d0508cc497cd466d90ab4a7a /src/05_oop.md
parent1e4fbaec81f3b641fedbcfdede9bac4f66a5288c (diff)
Add some protocols
Diffstat (limited to 'src/05_oop.md')
-rw-r--r--src/05_oop.md73
1 files changed, 72 insertions, 1 deletions
diff --git a/src/05_oop.md b/src/05_oop.md
index 816fd99..5e8f2c4 100644
--- a/src/05_oop.md
+++ b/src/05_oop.md
@@ -519,14 +519,85 @@ clase que defina un objeto en el que se puede buscar necesitas que sea un
### *Representable*: `__repr__`
+Este protocolo sirve para otorgar a python una forma de representar estos
+objetos. Al ejecutar la función `print` o al exponer valores en la REPL
+(recuerda que la P significa print), python trata de visualizarlos.
+
+La el método `__repr__` se ejecuta justo antes de imprimirse el objeto, de
+forma automática. La función requiere que se devuelva un elemento de tipo
+string, que será el que después se visualice.
+
+En el ejemplo a continuación se comienza con la clase `Dog` vacía y se
+visualiza una de sus instancias. Posteriormente, se reasigna la función
+`__repr__` de `Dog` con una función que devuelve un string. Al volver a mostrar
+a `bobby` el resultado cambia.
+
+Como se ve en el ejemplo, es interesante tener una buena función de
+representación si lo que se pretende es entender el contenido de los objetos.
+
+> NOTA: Python ya aporta una forma estándar de representar los objetos, si la
+> función `__repr__` no se define simplemente se usará la forma estándar.
+
+``` python
+>>> class Dog:
+... pass
+...
+>>> bobby = Dog()
+>>> bobby
+<__main__.Dog object at 0x7fb7fba1b908>
+
+>>> Dog.__repr__ = lambda self: "Dog called: " + self.name
+>>> bobby.name = "Bobby"
+>>> bobby
+Dog called: Bobby
+>>>
+```
+
### *Contable*: `__len__`
+En python se utiliza la función `len` para comprobar la longitud de cualquier
+elemento contable. Por ejemplo:
+
+``` python
+>>> len( (1,2,3) )
+3
+```
+
+Las objetos que soporten esta función podrán contarse para conocer su longitud
+mediante la función `len`. Python llamará al método `__len__` del objeto (que
+se espera que devuelva un número entero) y ésta será su longitud. Siguiendo con
+el ejemplo del protocolo anterior:
+
+``` python
+>>> Dog.__len__ = lambda self: 12 # Siempre devuelve 12
+>>> len(bobby)
+12
+```
+
+Este protocolo permite crear elementos contables, en lugar de los típicos
+diccionario, tupla y lista. Como por ejemplo los ya existentes `NamedTuple`,
+`OrderedDict` y otros. Los protocolos para el *buscable* e *iterable* también
+son muy interesantes para esta labor.
+
### *Buscable*: `__contains__`
-### *Creable*: `__init__`
+El método `__contains__` debe devolver `True` o `False` y recibir un argumento
+de entrada. Con esto el objeto será capaz de comprobarse con sentencias que
+hagan uso del operador `in` (y `not in`). Las dos llamadas del ejemplo son
+equivalentes. La segunda es lo que python realiza internamente al encontrarse
+el operador `in` o el operador `not in`.
+
+``` python
+>>> 1 in [1,2,3]
+True
+>>> [1,2,3].__contains__(1)
+True
+```
### *Iterable*: `__next__` e `__iter__`
+### *Creable*: `__init__`
+
### *Abrible* y *cerrable*: `__enter__` y `__exit__`
Que funcionen con el `with`