Definición Estándar de Python - wandent/mutual-wiki GitHub Wiki
[[TOC]]
A continuación, se listan las recomendaciones y mejores prácticas en estilo, documentación, reglas y ejemplos como guía de referencia para la codificación en Python tradicional y algunos puntos referentes al desarrollo con notebooks como Databricks y Jupyther. Este estándar se recomienda ser usado como guía; la guía deberá ser actualizada para agrupar los cambios en el lenguaje y adaptar al marco de trabajo establecido por cliente. Se recomienda incorporar los cambios metodológicos y descripción de las herramientas de desarrollo en guías a parte y centrar esta guía en estilos y normas propias de Python y algunas recomendaciones del uso de notebooks para este lenguaje. Ante casos de inconsistencia y contradicción, se recomienda guiarse bajo el concepto de experiencia en desarrollo, consultar con los desarrolladores más experimentados y retroalimentar el estándar. Estas prácticas se basan en los estándares oficiales liberados: PEP 8: Style Guide for Python Code, PEP 257: Docstring Conventions. Adicional, la experiencia en desarrollo de los autores del estándar.
Esta sección incluye las recomendaciones globales a nivel de código que se recomienda aplicar, se dividirá en diferentes componentes, en términos generales, son las reglas más recomendables de seguir tal cual están escritas.
Las funciones y librerías disponibles en Databricks y Apache Spark están en idioma inglés. Se tiene por estándar aceptado globalmente que el código y la documentación del código en los archivos fuentes se haga en inglés, lo anterior con la finalidad de favorecer la evolución en el código y habilitar a un público mayor para editar el código. Escribir el nombre de las funciones, código de ejecución, variables, documentación y demás componentes del código fuente en inglés.
Python depende de la indentación para lograr la separación de los bloques de ejecución, siguiendo el estándar PEP 8, se recomienda usar cuatro (4) espacios en blanco para definir un nivel de indentación. Para anidar el siguiente nivel, agregar otros cuatro espacios en blanco. Por defecto, varios editores de código realizan esta tarea de forma automática. Ejemplo:
Se recomienda no pasar de 72 caracteres por línea con la finalidad de garantizar que en la mayoría de las ventanas y editores se pueda visualizar dos lienzos de código.
Dado que hay casos donde se podría requerir una mayor longitud, se recomienda el uso de los backslashes () para separar las múltiples líneas de código, también es posible con paréntesis (‘(’,’)’) pero se recomienda no usar estos últimos en contextos con muchos paréntesis. Para el uso de la multilínea se debe indentar en un nivel. También se recomienda emplear los operadores en la siguiente línea, como operador se entiende de operaciones aritméticas (+, -, *, /) y operaciones de ejecución como punto (.).
Los códigos fuentes que no sean notebooks deben especificar la codificación UTF-8 para garantizar la menor cantidad de incidentes asociados a codificación del texto. Esto se hace usando como primera línea o segunda (si se define en la primera la ruta del ejecutable).
-
Ejecución que no es desde notebook: Cada archivo fuente que sea el punto de ejecución deberá contener un punto de entrada
__main__
donde estará la lógica macro del programa.
-
Ejecución desde Notebook: Se recomienda que clases, constantes y métodos se definan al principio del notebook. Luego, una línea de comando con marcador (markdown) # Start Point o con un comentario usando triple comilla
"""Start Point"""
.
Se recomienda usar comillas dobles en la mayoría de los casos para delimitar la cadena de texto, usar comillas sencillas si se tiene texto con comillas dobles.
Al implementar clases y funciones de una biblioteca (librería) se recomienda usar la semántica from . import as Si se supera más de cinco (5) elementos de la misma biblioteca (librería), cambiar por import .
Se recomienda usar el bloque “with” para operaciones que involucren abrir escritura o lectura, ya sea a archivos o a bases de datos, siempre que sea posible.
Los comentarios en código son obligatorios para explicar la lógica de negocio, debe ser en inglés y se tienen los siguientes tipos definidos de documentación.
Se recomienda documentar líneas de lógica compleja y cuyo nombre no permita inferir la acción que se está ejecutando. La línea de documentación se agregará en la parte superior de la línea de código usando numeral (#), es decir: una línea antes. Debe cumplirse con la norma de cantidad de caracteres en línea y ser preciso con el comentario. Todo comentario in-line lleva la misma indentación de la línea de código que se está documentando.
Se recomienda documentar cada método, sea de clase, instancia o global con la siguiente información:
- Documentar en bloque usando tres comillas de apertura y tres de cierre.
- Mantener la indentación del primer nivel contenido del método.
- El Primer párrafo contiene una descripción del método.
- Dejar sin contenido la segunda línea.
- Indicar los parámetros, incluso los internos e indicar qué son.
- Indicar las posibles salidas del método y mencionar casos de posible excepción.
- Dar un ejemplo de uso del método.
- Dejar una línea en blanco luego del ejemplo de uso.
- Indicar el autor del método, versión, fecha creación. Actualizado por, actualizado por, cambios hechos.
Cuando se presente métodos cortos, de no más de 5 líneas, se recomienda documentar en una sola línea señalando el resultado, se recomienda siempre indicar el autor. Usar triple comillas in-line:
Las clases también deben tener documentaciones completas:
- Utilizar triple comillas para documentar en bloque.
- Usar la indentación del nivel siguiente a la declaración de la clase.
- La primera línea indicar el uso de la clase.
- Dejar la segunda línea en blanco.
- Indicar el contenido de la clase: constantes, variables, métodos de clase, métodos de instancia.
- Dejar un espacio en blanco luego de la información de contenido.
- Agregar información del autor, versión, fecha creación, actualizado por, actualizado en y cambios.
- El código se separa en secciones: Constants, variables, static methods, class methods, methods, en el mismo orden señalado. Usar estos títulos para documentar cada sección una línea antes de iniciar el código respectivo y usar triple comilla in-line.
En términos generales, se espera que las variables sean lo suficientemente descriptivas con sus nombres para reducir el esfuerzo en la documentación, se plantean las siguientes recomendaciones:
- Las constantes van en mayúscula, si el nombre está compuesto por varias palabras separar con guion bajo (_).
- No usar nombres como “i” o “j” para describir variables ya que no se relacionan con la lógica de negocio.
- Las variables normales deben ir en minúscula, si está compuesta por varias variables usar como separador el guion bajo (_).
- Se recomienda no superar el uso de 4 palabras compuestas para nombrar una variable.
- Cuando se trate de nombres compuestos por dos o más palabras usar guion bajo (_).
- En clases, ubicar primero las constantes y debajo las variables.
- Evitar caracteres especiales y la letra ñ.
- Se recomienda encapsular los atributos de las clases y sólo exponer el acceso a los mismos usando métodos, esto se hace anteponiendo dos guiones bajos al nombre de la variable. Considerar también el uso del decorador @property. Un ejemplo aquí.
Seguir las siguientes recomendaciones de estilo:
- No usar mayúsculas en los nombres de los métodos.
- Iniciar el nombre con un verbo que referencie lo que hace el método, ejemplo: calculate, read, write, stop, is_valid.
- Se recomienda usar como prefijo el tipo de dato de los parámetros que recibe el método. Excepción: argumentos internos como los métodos de clase y objeto donde se recomienda que el parámetro interno para clases se represente como cls y para objetos usar la palabra reservada self. Los prefijos son: int, flo (float), com (complex), str (string), lis (list), tup (tuple), set (set), dic, (dictionary), obj (object, objeto de clase).
- Se recomienda el uso del decorador @staticmethod para los métodos estático que sean utilitarios, de esta forma se le asocia la pertenencia a una clase.
- Se recomienda no superar las veinticinco (25) líneas de código (sin incluir comentarios) por método contando desde la firma y evitar superar cuatro (4) niveles de indentación, si se están superando estos valores se recomienda desglosar en más métodos.
- Todo método debe tener un retorno explícito, incluso si el retorno es solo None o texto de información.
Considerar las siguientes reglas para las clases:
- Los nombres de las Clases empiezan con Mayúscula.
- Los nombres compuestos no llevan guiones, cada palabra inicia con mayúscula.
- Se recomienda poner de prefijo U para las clases utilitarias, D para las clases de dominio.
-
El orden de los componentes de las clases es: firma de clase, constantes, variables, métodos estáticos, métodos de clase, métodos de objeto.
-
La clase, variables y los métodos deben cumplir con la documentación requerida.
-
En los notebooks y en los archivos fuente de Python, se recomienda siempre contar con al menos una clase de utilitarios para el manejo de las constantes y encapsulación.
Considerar el ejemplo de la clase USiniestro, la cual es una clase de utilitarios:
En el caso de los archivos fuentes, se recomienda el uso del módulo Logging https://docs.python.org/3/library/logging.html. Se recomienda:
- Configurar dos (2) handlers: Stream handler para pantalla y File Handler para persistir. https://docs.python.org/3/library/logging.handlers.html#module-logging.handlers.
- El formato sugerido para el log es: '%(asctime)-15s %(component)s %(level)s %(message)s' donde “component” es la clase o método de donde se está usando el log.
- Ejemplos en https://docs.python.org/3/howto/logging.html.
Resultado esperado:
2005-03-19 15:38:55,977 - simpleExample - DEBUG - debug message
2005-03-19 15:38:55,979 - simpleExample - INFO - info message
El rendimiento y la captura de información de los notebooks deberá hacerse por medio de Application Insights, no se ofrece reglas o estándar al respecto, pero puede encontrarse un ejemplo en: https://docs.microsoft.com/en-us/archive/msdn-magazine/2018/june/azure-databricks-monitoring-azure-databricks-jobs-with-application-insights.
En esta sección se describirán las recomendaciones para el trabajo con notebooks y sugerencia de estructura recomendada para los espacios de trabajos de Databricks.
Se recomienda contar con una carpeta a nivel del Área de Trabajo donde se almacenen los notebooks comunes lo que permitirá restringir accesos en caso de que se requiera y se habilitará la edición al equipo colaborador.
Dentro de Common, la cual es la carpeta compartida, se recomienda separar los notebooks y las librerías. Los notebooks tendrán las acciones en común como garantizar que los puntos de montaje estén listos y las librerías son las funcionalidades que se agregarán al espacio de trabajo. Tenga en cuenta que las librerías cargadas a la carpeta tienen alcance de área de trabajo, también hay de alcance de notebook. Para más información consultar en: https://docs.databricks.com/libraries.html#uploading-libraries. Nota: Databricks recomienda como paso previo desinstalar del clúster la librería que vaya a ser borrada del workspace.
- Se recomienda que los notebooks sean nombrados en minúscula, usar guión bajo para separar los nombres compuestos.
- Los nombres de las librerías en minúscula, usar guion bajo para separar los nombres compuestos.
- El nombre de las carpetas debe iniciar en mayúscula.
- Librerías: Seguir las recomendaciones descritas en la sección de importación de librerías, este será el punto inicial de las librerías.
- Utilidades: Después de las librerías, debería seguir los llamados a los notebooks de utilidades que contienen las funciones ya implementadas a utilizar.
- Conexiones: Va después de las utilidades, es la ejecución necesaria para conectar con las diferentes fuentes y destinos, esto debe incluir las conexiones con las bases de datos u otros sistemas. Es probable que ciertas conexiones estén en un notebook (preferido) y otras estén en código del notebook. Siempre considerar si es posible promover los métodos de conexión a un nuevo sistema a un notebook común de conexión.
- Variables y constantes: Aplican las reglas de nombramiento, también se recomienda incluir en este espacio la generación de los parámetros de widget y su obtención, pero no la asignación o inicialización de las variables de control que vienen de esos parámetros.
- Lectura de parámetros: Después de las variables, se leen los parámetros de archivos de configuración y demás. Se recomienda poner la mayor cantidad de parámetros en un archivo JSON y poner las claves de configuración siempre en mayúscula. Recuerda poner las credenciales y datos sensibles en Key Vault y no en los archivos de configuración. Una estrategia para reducir el esfuerzo inicial de desarrollo es primero tener las diferentes variables como constantes y luego cuando las funcionalidades estén desarrolladas pasarlas a los valores que vayan en los archivos de configuración.
- Preparación de esquemas para lectura: Se recomienda siempre proveer un esquema para leer datos desde una fuente (no aplica para tablas ya existentes) ya que aumenta la velocidad de lectura de Databricks, como buena práctica se recomienda usar métodos para leer los esquemas desde archivos de configuración y preparar el objecto de esquema. Este paso se hace luego de leer los parámetros.
- Métodos específicos al notebook: Cuando se desarrolle una función o transformación que depende altamente de la estructura de los datos actuales o sean la implementación puntual de un caso de uso, estos métodos se ponen en este espacio, que va luego de la definición de esquemas.
- Punto de inicio: En este punto inicia las transformaciones y exploración de los datos, se orquesta la ejecución de los métodos implementados más arriba o que vienen de las utilidades, se recomienda aplicar los puntos de documentación comentados más arriba y reflejar la lógica del negocio.
- Databricks. (16 de enero de 2020). Libraries. Obtenido de Documentation Databricks: https://docs.databricks.com/libraries.html#uploading-libraries.
- Python.org. (07 de enero de 2020). PEP 257 -- Docstring Conventions. Obtenido de Python.org: https://www.python.org/dev/peps/pep-0257.
- Python.org. (07 de enero de 2020). PEP 8 -- Style Guide for Python Code. Obtenido de Python.org: https://www.python.org/dev/peps/pep-0008.