Continúo hoy con una nueva entrega del análisis de los lenguajes de programación que están más de actualidad, y ya van cinco con esta. En las anteriores entregas de esta serie de posts analizamos C/C++ y C#, Java/JavaScript, Rust, Go y hoy (a petición popular) le toca el turno a Python
.
Como siempre en esta serie de posts, un poco de visión histórica del lenguaje.
Python
nace de la mente de Guido van Rossum, holandés de pro, alrededor de principios de los años 90, como sucesor de un lenguaje llamado ABC
diseñado para poder enseñar programación a usuarios que no fuesen desarrolladores profesionales. Aunque ABC
no tuvo mucho éxito, Guido se llevó la idea de la simplicidad y facilidad de asimilación de ABC
a otro proyecto para el desarrollo de un S.O. distrubido (Amoeba) y partiendo de ahí quiso crear un lenguaje de scripting con las premisas de ABC
(sí, queridos niños, Python
surgió como lenguaje de scripting, ¿o qué os pensábais?)
Python 2.0 se publicó en Octubre del año 2000, y desde entonces se han publicado múltiples versiones. De hecho, merece la pena hacer indicar que en la actualidad hay dos «major versions» de Python
. La versión Python 2.x y la versión Python 3.x. Esta doble rama de versiones se originó cuando se realizó en 2008 la revisión del lenguaje al publicar Python 3.0. En ese momento se decidió (por la comunidad de PEP) que esa nueva versión 3.0 no fuera completamente compatible hacia atrás con las versiones anteriores. Es evidente que ya había una comunidad extensa comunidad de desarrolladores de Python 2.x y mucho código que se quedaría en una rama con fecha de caducidad (en primer instancia hasta 2015, fecha del «end of support» de Python 2.x) por lo que se hicieron varias cosas. Primero, se hizo un «backport» o «retroimplementación» de muchas de las novedades de la versión 3.0 en las versión 2.6.x y 2.7.x. También, aunque la versión 2.7 terminaría su vida en 2015, se decidió extenderla, al menos de primeras, hasta 2020 (veremos que ocurre en el último momento). Es por esto que Python tiene 2 «major versions» vigentes a fecha de hoy.
Premisas de diseño
Para seguir con la estructura habitual del análisis en esta serie de posts comentaremos las premisas de diseño que dirigieron la implementación del lenguaje:
- Facilidad de lectura y comprensión del código fuente
- Plataforma extensible
- Aunar programación declarativa, con OOP y también construcciones de la programación funcional
- Plataforma de propósito múltiple siendo recomendable tanto para pequeñas bases de código fuente como para proyectos o sistemas de gran tamaño
- ¿¡Divertido!?. De hecho su nombre deriva del grupo cómico «Monty Python» tan famoso en las décadas de los 70 y los 80.
Características Principales
Pasemos a enumerar sus características principales más destacables:
- Sintaxis basada en indentación poscional. Prescinde de los «curly brackets» lo cual ya supone una diferencia visual con casi cualquier lenguaje de los últimos años. Aquí ya no hay discusión entre si prefieres el tipo de indentado de Kernigan&Ritchie o el Allman o el de GNU. De hecho una de las especificaciones de la comunidad
Pyton
, la PEP 8, indica claramente cómo debe ser el indentado en el lenguaje. - Es un lenguaje interpretado, al menos en su implementación de referencia
CPython
. - Gestión de memoria basada en «garbage collector» (que incluso detecta referencias cíclicas) y con «duck-typing» aunque con tipado estático.
- Manejo de errores mediante excepciones y construcciones «
try/catch
« - Programación OOP con clases y métodos, aunque con ciertas características que le hacen un poco «especial«:
- No soporta definición de acceso a los miembros de una clase por ejemplo ( se aconseja cierta convención con el símbolo «underscore» para ocultar los miembros no públicos de una clase, pero esta convención no evita que podamos acceder a dicho miembro privado de una clase)
- Soporta herencia (incluso herencia múltiple) y polimorfismo
- No hay declaración de «interfaces» ni clases abstractas
- Su «éxito» como lenguaje de programación en lo que tiene que ver con el «Data Science» y/o «Machine Learning» en parte viene dado por su manejo de listas, tuplas, sets, maps, slices, definición por comprensión de las listas, iteradores y generadores.
- Maneja el concepto de «módulos» lo que contribuye a la encapsulación y la extensibilidad del lenguaje
- El lenguaje está acompañado por una «Standard Library» que le permite ser prácticamente un framework multipropósito
- Soporta expresiones «lambda»
- Fuerte comunidad de desarrolladores y «fans» que además dirige su evolución y su roadmap mediante las especificaciones PEP («Python Enhancement Proposal») similares en concepto con las RFC («Request for Comments» de la época internet
A continuación, como es habitual en nuestra serie de posts, os dejo un pequeño ejemplo de código para que os hagáis una idea de qué aspecto tiene el código fuente en Python
:
class greeter(object): # the duck said: it's a list of strings, isn't it? _msg_strings = ["Hello World!", "This is an list example"] # yes, this is a constructor man! def __init__(self, name): self._name = name def greet(self, other_msg): print("This is the method greet() working...") # let's iterate the instance variable for msg in self._msg_strings: print(msg) #additionally let's show the parameter print(other_msg) # this is an 'executable' module if __name__ == "__main__": o = greeter("Javier") o.greet("This is an additional message") |
Como podréis ver, la sintáxis al principio cuesta de entender cuando vienes de lenguajes «curly-bracket» pero una vez te acostumbras al indentado y las reglas básicas de estilo es agradable.
Paso ahora a comentar qué aspectos del lenguaje me han parecido positivos y cuales no me han terminado de convencer.
Consideraciones
Como ya he comentado, el lenguaje me parece interesante, si bien es cierto que considero que parte de su éxito actual no se debe a sus premisas de diseño sino más bien a su simplicidad (y otros factores que comentaré más adelante).
Aunque no haya un estudio fiable comparando el rendimiento de Python
con otros lenguajes (incluidos algunos de los comentados en esta serie de posts) el que sea un lenguaje interpretado creo que lo penaliza. Aprovecho para indicar que tenéis los comentarios del post para que aportéis cualquier evidencia a favor o en contra de lo que comento.
En lo referente a la programación orientada a objetos, es evidente que el lenguaje no tiene gran potencia sintáctica comparado con otros como C# o Java, pero claro, no se puede diseñar un lenguaje simple y que a la vez tenga todos los recursos de otros lenguajes diseñados específicamente para ello. Por otro lado, esto permite que su curva de aprendizaje tenga una pendiente más pronunciada al menos para llegar a un nivel general de OOP.
Me parece atractivo su soporte para programación funcional pues creo que le confiere flexibilidad sin caer en las complicaciones de otros lenguajes más «funcionales» (todavía recuerdo con escalofríos Lisp
o Caml
). Aquí creo que radica también su popularidad actual entre la comunidad de Data Scientists y desarrolladores de Machine Learning o Deep Learning. De hecho múltiples frameworks como TensorFlow, Keras, Scikit-Learn, PyTorch o el tristemente extinto CNTK están implementados como módulos de Python
.
Su flexibilidad y su adaptabilidad a diferentes propósitos o tipologías de proyectos me gusta pero me hace dudar al mismo tiempo. Nunca ha habido un lenguaje que fuese idóneo en todos los ámbitos y dudo que Python
lo sea, especialmente cuando además su simplicidad sintáctica y sus carencias en OOP no contribuyen en algunos de esos tipos de proyectos.
En conclusión, Python es un lenguaje tremendamente popular hoy en día, y ha de ser tenido en cuenta tanto si queremos poner al día nuestras capacidades como desarrollador «fullstack» como si queremos entrar en el demandado y actual mundo de los proyectos de Inteligencia Artificial. Esto queda patente si tenemos en cuenta que Python ha sido Lenguaje del Año para el índice TIOBE en 2007, 2010 y recientemente en 2018 – creo que merecería hacer una restrospectiva para analizar ese título en las decadas anteriores –
Este ha sido el penúltimo post sobre la serie de análisis de lenguajes de programación. En el siguiente (y último) post de la serie, haremos una pequeña recapitulación de lo más destacado de la serie por si alguno sois de los que gusta del consabido TL;DR