diff options
-rw-r--r-- | src/08_stdlib.md | 371 |
1 files changed, 371 insertions, 0 deletions
diff --git a/src/08_stdlib.md b/src/08_stdlib.md new file mode 100644 index 0000000..3ac1542 --- /dev/null +++ b/src/08_stdlib.md @@ -0,0 +1,371 @@ +# La librería estándar + +La librería estándar se refiere a todas las utilidades que un lenguaje de +programación trae consigo. Los lenguajes de programación, a parte de aportar la +propia funcionalidad del lenguaje en sí mismo que simplemente sería la +ejecución del código fuente que se le indique, suelen incluir funcionalidades +que no están necesariamente relacionadas con ese proceso. + +El motivo de esto es facilitar el uso del lenguaje para las labores más +comunes, incluyendo el código necesario para realizarlas sin necesitar añadidos +externos. + +En lenguajes de programación de dominio específico la librería estándar suele +contemplar muchos casos de ese dominio concreto. Por ejemplo, el lenguaje de +programación Julia, aunque esté diseñado con el objetivo de ser un lenguaje +válido para cualquier uso, su área de trabajo se centra en el entorno +científico. Es por eso que incluye en su librería estándar paquetes de álgebra +lineal, estadística y otros. + +Existen muchas diferentes aproximaciones a la librería estándar. Algunos +lenguajes las mantienen extremadamente reducidas con el fin de que la +implementación del lenguaje sea más liviana, con la contrapartida de forzar a +quien los use a tener que utilizar herramientas externas o a desarrollarlas. + +Python es un lenguaje de propósito general con una extensísima librería +estándar. Esto dificulta la selección de apartados a mostrar en este capítulo, +pero facilita la programación de cualquier aplicación en éste lenguaje. + +Los paquetes estándar de python facilitan la lectura de infinidad de tipos de +fichero, la conversión y el tratamiento de datos, el acceso a la red, la +ejecución concurrente, etc. por lo que librería estándar es más que suficiente +para muchas aplicaciones y no se requiere añadir módulos externos. + +Conocer la librería estándar y ser capaz de buscar en ella los paquetes que +necesites te facilitará mucho la tarea, evitando, por un lado, que dediques +tiempo a desarrollar funcionalidades que el propio lenguaje ya aporta y, por +otro, que instales paquetes externos que no necesitas. + +Todos los apartados aquí listados están extremadamente bien documentados en la +página oficial de la documentación de python y en la propia ayuda. Eso sí, +tendrás que importarlos para poder leer la ayuda, pero ya sabes cómo se hace. + +A continuación se recogen los módulos más interesantes, aunque en función del +proyecto puede que necesites algún otro. Puedes acceder al listado completo en +la página oficial de la documentación[^stdlibdoc]. + +[^stdlibdoc]: <https://docs.python.org/3/library/index.html#library-index> + + +## Interfaz al sistema operativo: `os` + +Ya definimos previamente el concepto *interfaz* como superficie de contacto +entre dos entidades. Esta librería facilita la interacción entre python y el +sistema operativo. + +La comunicación con el sistema operativo es primordial para cualquier lenguaje +de programación de uso general, ya que es necesario tener la capacidad de hacer +peticiones directas al sistema operativo. Por ejemplo, cambiar de directorio +actual para facilitar la inclusión rutas relativas en el programa, resolver +rutas a directorios y un largo etc. + +En capítulos previos hemos hablado de las diferencias entre sistemas +operativos. Esta librería, además, facilita el trabajo para esos casos. Por +ejemplo, que el separador de directorios en UNIX es `/` y en Windows `\`, si +quisiéramos programar una aplicación multiplataforma, nos encontraríamos con +problemas. Sin embargo, el módulo `os.path` dispone de herramientas para +gestionar las rutas de los directorios por nosotros, por ejemplo, la variable +`os.path.sep` (copiada en `os.sep` por abreviar), guarda el valor del separador +del sistema en el que se esté ejecutando la aplicación: `/` en UNIX y `\` en +Windows. + +Este paquete es muy interesante para desarrollar código portable entre las +diferentes plataformas. + +## Funciones relacionadas con el intérprete: `sys` + +Aunque el nombre de este módulo suene complicado, su uso principal es el de +acceder a funcionalidades que el propio python controla. Concretamente, se usa +sobre todo para la recepción de argumentos de entrada al programa principal, +la redirección de entradas y salidas del programa y la terminación del +programa. + +### Salida forzada: `sys.exit()` + +Para salir de forma abrupta del programa y terminar su ejecución, python +facilita la función `sys.exit()`. Al ejecutarla la + +### *Standard streams*: `sys.stdin`, `sys.stdout` y `sys.stderr` + +Cuando se trabaja en programas que funcionan en la terminal se pueden describir +tres vías de comunicación con el usuario: + +1. El teclado: de donde se obtiene lo que el usuario teclee mediante la función + `input`. +2. La pantalla: a donde se escribe al ejecutar la función `print`. +3. Y la salida de errores: Una salida especial para los fallos, similar a la + anterior, pero que se diferencia para poder hacer un tratamiento distinto y + porque tiene ciertas peculiaridades distintas. Los mensajes de error de + excepciones se envían aquí. + +Estas tres vías se conocen comúnmente como entrada estándar (*standard input*), +`stdin`, salida estándar (*standard output*), `stdout`, y error estándar +(*standard error*), `stderr`. Este concepto responde al nombre de *standard +streams* y es una abstracción de los dispositivos físicos que antiguamente se +utilizaban para comunicarse con una computadora. Hoy en día, estos tres +*streams* son una abstracción de esa infraestructura y se comportan como +simples ficheros de lectura en el primer caso y de escritura en los otros dos. + +Los diferentes sistemas operativos los implementan a su modo, pero desde el +interior de python son simplemente ficheros abiertos, como si se hubiese +ejecutado la función `open` en ellos y ellos se encargan de leer o escribir a +la vía de interacción con el usuario correspondiente. Es decir, en realidad +`print`, `input`, etc. son únicamente funciones que facilitan la labor de +escribir manualmente en estos *streams*: + +``` python +>>> import sys +>>> chars = sys.stdout.write("Hola\n") +Hola +>>> chars # Recoge el número de caracteres escritos +5 +``` + +La realidad es que estos *streams* dan una flexibilidad adicional muy +interesante. Como son únicamente variables de ficheros abiertos pueden +cerrarse y sustituirse por otros, permitiéndote redireccionar la entrada o la +salida de un programa a un fichero. + +El siguiente ejemplo redirecciona la salida de errores a un fichero llamado +`exceptions.txt` y trata de mostrar una variable que no está definida. Python +en lugar de mostrar el mensaje de una excepción, la escribe en el fichero al +que se ha redireccionado la salida: + +``` python +>>> sys.stderr = open("exceptions.txt", "w") +>>> aasda # No muestra el mensaje de error +>>> +>>> with open("exceptions.txt") as f: +... f.read() # Muestra el contenido del archivo +... +'Traceback (most recent call last):\n File "<stdin>", line 1, in \ +<module>\nNameError: name \'aasda\' is not defined\n' +``` + + +### Argumentos de entrada: `sys.argv` + +Es posible añadir argumentos de entrada a la ejecución de los programas. Piensa +en el propio programa llamado python, al ejecutarlo en la shell de sistema se +le pueden mandar diferentes opciones que, por ejemplo, digan qué módulo debe +ejecutar: + +``` bash +python test.py +``` + +Para la shell de sistema, todo lo que se escriba después de la primera palabra +es considerado un argumento de entrada. + +Cuando se ejecutan nuestros programas escritos en python, es posible también +enviarles argumentos de entrada: + +``` bash +python test.py argumento1 argumento2 ... +``` + +Lo que el python reciba después del nombre del módulo a ejecutar lo considerará +argumentos de entrada de nuestro módulo y nos lo ordenará y dejará disponible +en la variable `sys.argv`, una lista de todos los argumentos de entrada. + +Si muestras el contenido de la variable en la REPL, te responderá `['']` ya que +la REPL se ejecuta sin argumentos. Sin embargo, si creas un módulo y le añades +este contenido: + +``` python +import sys +print(sys.argv) +``` + +Verás que se imprime una lista con el nombre del archivo en su primer elemento. + +Si ejecutas el módulo desde la shell de sistema añadiéndole argumentos de +entrada: + +``` bash +python modulo.py arg1 arg2 arg3 +``` + +La lista `sys.argv` recibirá todos, siempre a modo de string. + +Los argumentos de entrada son extremadamente interesantes para permitir que los +programas sean configurables por quien los use sin necesidad de tener que +editar el código fuente, cosa que nunca debería ser necesaria a menos que +exista un error en éste o quiera añadirse una funcionalidad. + +## Procesamiento de argumentos de entrada: `argparse` + +Como la variable `sys.argv` entrega los argumentos de entrada tal y como los +recibe y no comprueba si son coherentes, python dispone de una librería +adicional para estas labores. El módulo `argparse` permite definir qué tipo de +argumentos de entrada y opciones tiene tu programa y qué reglas deben seguir. +Además, facilita la creación de ayudas como la que se muestra cuando ejecutas +`python -h` o `pip -h` en la shell de tu sistema. + +Es una librería bastante compleja con infinidad de opciones que es mejor que +leas en la propia documentación cuando necesites utilizarla. + +## Expresiones regulares: `re` + +Las expresiones regulares (*regular expression*, también conocidas como +*regexp* y *regex*) son secuencias de caracteres que describen un patrón de +búsqueda. + +En python se soportan mediante el módulo `re` de la librería estándar. + +## Matemáticas y estadística: `math` y `statistics` + +El módulo `math` soporta gran cantidad de operaciones matemáticas avanzadas +para coma flotante. En él puedes encontrar logaritmos, raíces, etc. + +El módulo `statistics` soporta estadística básica como medias, medianas, +desviación típica, etc. + +Ambos módulos tienen mucho interés ya que python se usa extensivamente en el +análisis de datos. Aunque tiene librerías de terceros mucho más adecuadas para +esta labor, para proyectos pequeños puede que sea suficiente con estos módulos. + +## Protocolos de internet: `urllib` + +`urllib` es un conjunto de paquetes que permiten seguir URLs o enlaces, +principalmente para HTTP y su versión segura HTTPs. Soporta cookies, +redirecciones, autenticación básica, etc. + +El siguiente ejemplo te muestra cómo descargar el primer boceto del estándar +del protocolo HTTP de la página web del IETF. Recordando los apartados previos, +fíjate en el uso de la sentencia `with` y en el uso de los corchetes para +obtener un número limitado de caracteres de la recién decodificada respuesta. + +``` python +>>> from urllib.request import urlopen +>>> with urlopen("https://tools.ietf.org/rfc/rfc2068.txt") as resp: +... print( resp.read().decode("utf-8")[:1750] ) +... + + + + + + +Network Working Group R. Fielding +Request for Comments: 2068 UC Irvine +Category: Standards Track J. Gettys + J. Mogul + DEC + H. Frystyk + T. Berners-Lee + MIT/LCS + January 1997 + + + Hypertext Transfer Protocol -- HTTP/1.1 + +Status of this Memo + + This document specifies an Internet standards track protocol for the + Internet community, and requests discussion and suggestions for + improvements. Please refer to the current edition of the "Internet + Official Protocol Standards" (STD 1) for the standardization state + and status of this protocol. Distribution of this memo is unlimited. + +Abstract + + The Hypertext Transfer Protocol (HTTP) is an application-level + protocol for distributed, collaborative, hypermedia information + systems. It is a generic, stateless, object-oriented protocol which + can be used for many tasks, such as name servers and distributed + object management systems, through extension of its request methods. + A feature of HTTP is the typing and negotiation of data + representation, allowing systems to be built independently of the + data being transferred. + + HTTP has been in use by the World-Wide Web global information + initiative since 1990. This specification defines the protocol + referred to as "HTTP/1.1". + +>>> +``` + +## Fechas y horas: `datetime` + +`datetime`, que ya ha aparecido anteriormente, es un módulo para gestión de +fecha y hora. `datetime` soporta gran cantidad de operaciones y tipos de dato. +Entre ellos los `timedeltas`, diferencias temporales que te permiten sumar y +restar fechas con facilidad con los operadores habituales. + +Con las facilidades de `datetime`, es poco probable que necesites importar una +librería de gestión de fecha y hora independiente. + +## Procesamiento de ficheros: `json` y `sqlite3` + +Python habilita gran cantidad de procesadores de formatos de fichero, los dos +que se lista en este apartado tienen especial interés. + +El primer módulo, `json`, sirve para manipular datos en formato JSON. Sus dos +funciones principales `dumps` y `loads` vuelcan o cargan datos de JSON a +diccionarios o listas en una sola orden debido que la propia estructura de JSON +está formada por parejas clave valor o listas de valores ordenadas por índices. +Esta es la razón por la que en muchas ocasiones se utilizan ficheros de formato +JSON para intercambiar información entre aplicaciones de python: su lectura y +escritura es extremadamente sencilla. + +El segundo módulo, `sqlite3`, facilita el acceso a ficheros en formato SQLite3, +un formato binario con una interfaz de acceso que permite consultas SQL. El +módulo `sqlite3` es capaz de convertir las tablas que SQLite3 retorna a +estructuras de python de forma transparente y cómoda por lo que es un aliado +interesante para aplicaciones que requieren una base de datos pequeña y +resiliente. + +## Aritmética de coma flotante decimal: `decimal` + +En el apartado sobre datos tratamos la complejidad de los números de coma +flotante y que su representación binaria puede dar lugar a problemas. Este +módulo de aritmética decimal aporta una solución rigurosa a este problema con +el fin de facilitar el uso de python en entornos que requieren precisión +estricta que incluso puede requerir cumplir con normativas, como puede ser la +banca. + +La documentación del módulo muestra un par de ejemplos muy interesantes usando +la clase `Decimal` aportada por este. Se adjuntan a continuación para que los +estudies y los disecciones en busca de las diferencias con el uso de los +números de coma flotante normales: + +``` python +>>> from decimal import * +>>> round(Decimal('0.70') * Decimal('1.05'), 2) +Decimal('0.74') +>>> round(.70 * 1.05, 2) +0.73 + +>>> Decimal('1.00') % Decimal('.10') +Decimal('0.00') +>>> 1.00 % 0.10 +0.09999999999999995 + +>>> sum([Decimal('0.1')]*10) == Decimal('1.0') +True +>>> sum([0.1]*10) == 1.0 +False +``` + +## Lo que has aprendido + +Más que aprender, en este apartado has sobrevolado la librería estándar de +python desde la distancia y te has parado a observar qué problemas comunes ya +están resueltos en python. + +La realidad es que la librería estándar es mucho más extensa que lo listado en +este apartado, pero aquí se han mencionado los módulos que más frecuentemente +se suelen usar en entornos normales y algunos otros que tienen interés a la +hora de afianzar conocimiento que has obtenido en capítulos previos, como es el +caso del módulo `decimal`. + +Este capítulo empieza a mostrarte el interés de programar en python y las +posibilidades que tienes con él, únicamente con la librería estándar. En el +próximo verás la cantidad de funcionalidad adicional que le puedes añadir con +un par de librerías escritas por terceros. + +Sirva también este capítulo como recordatorio de lo extensa que es la librería +estándar de python. En el futuro, cuando tengas intención de buscar una +librería para resolver un problema que te despista de trabajar en la +funcionalidad principal de tu aplicación, empieza por la librería estándar. |