Feb 19

Diabólico python … ¿o son cosas mías?

 

El otro día me dio por retomar python y en concreto, me puse a ver cómo podía enviar y recibir correos con python y gmail. Y la verdad, es cada vez entiendo menos el éxito de python.

Me puse a googlear, para ver cómo se hacía lo del envío y recepción de correo. Sobre el envío hay muchos ejemplos y tutoriales, no me costó mucho hacer un poco de copy-paste de esos ejemplos, ajustarlos a lo que quería y ponerlos en marcha. La recepción de correos es otro tema, apenas hay tutoriales o, por lo menos, no los he encontrado, salvo uno que parece copiado una y otra vez que es el de ver cuántos correos tengo y sacar por pantalla, en bruto, lo que recibimos del servidor. No me extraña, porque python se usa sobre todo con aplicaciones web y en estas aplicaciones web lo habitual es enviar correos, no leerlos. Me costó un montón encontrar cómo se "parsea" el mensaje leido, para extraer sus adjuntos, el texto, etc, etc. Al final encontré un ejemplo en un foro perdido de alguien que lo había puesto para contestar a alguien.

Pero bueno, eso son mis peripecias concretas y no tienen nada que ver con que python sea bueno o malo. Las cosas que veo mal de python son las siguientes:

Por un lado, al no ser en absoluto tipado, me da la impresión de que debe ser muy, pero que muy complejo, hacer y mantener un programa grande. O pones muy buenos comentarios, o nunca sabrás qué te esta llegando como parámetro en una función, qué tienes que pasar como parámetro a una función o qué te devuelve una función.

Los IDE lo tienen bastante dificil con los autocompletar. Desde luego la sintaxis coloreada ayuda mucho, pero lo fundamental para mí de un IDE es el autocompletar. Sin necesidad de ir a mirar dónde está definida la clase o sin tener que ir a la documentación, tener accesible qué métodos tiene y qué parámetros puedo pasarle. Eso, en python, con un IDE, es poco menos que imposible, salvo quizás (no lo he probado), que se haga el "new" en el mismo sitio. El único autocompletar que he visto lo que hace es ponerte los métodos que ya has usado para esa variable poco más arriba en el código. El primer autocompletar de esa variable sale vacío, el segundo sale con el método que hayas usado en el primero y así sucesivamente.

Bueno, el autocompletar, aunque es una ayuda importante, no sería tan grave si la documentación estuviera en condiciones. Pero me temo que, al menos para mí, tampoco es así. Con esto del correo me he ido a la documentación, a ver los métodos de clases como POP3_SSL o SMTP. Vamos, por ejemplo, al método list() de POP3 o el retr() que está justo detrás. Bien, ambos devuelven una cosa estilo (response, ['message num_octects', ... ], octects). ¡¡ Mande !!. Lo de response pone más arriba que es el texto de respuesta del servidor, así que en principio no hay mucha pega. Lo de message num_octects… bueno, intuiremos que es un string por aquello de que está entre comillas, intuiremos que es el número de bytes del mensaje y que esa lista tiene tantos números-string como mensajes. Lo del octects del final ya se me escapa. También es cierto que eso que hemos intuido del segundo parámetro, lo he intuido después de haber hecho el ejemplo, porque en mi primera lectura me sonó a chino.

Dicen que la ventaja de python sobre java es que se escribe menos código (ver imagen), pero mi impresión es que cuesta más escribirlo. Y desde luego, me hace la impresión de que cuesta muchísimo más mantenerlo. Pero si tiene el éxito que tiene y se usa tanto, supongo que todo esto en realidad son las impresiones de un novato mal acostumbrado a java. Seguramente estoy equivocado y tendré que seguir con ello para ver si llego a acostumbrarme.

Las mujeres piensan en java, los hombres en python.

May 01

Python con MySQL

 

Hay una tontería de la conexión de python con MySQL que me ha llamado la atención y aprovecho para comentar aquí. El tema es que según obtengamos el cursor de la conexión para hacer las consultas, podemos acceder a los resultados de una manera o de otra.

Si obtenemos el cursor de esta manera

conn = MySQLdb.connect (….)
cursor = conn.cursor()

una vez que hagamos una consulta y obtengamos una de las filas resultado, debemos acceder a cada uno de los campos usando un índice de un array

cursor.execute ("select * from tabla")
fila = cursor.fetchone()
# para acceder al primer campo
print fila[0]  

Sin embargo, al obtener el cursor podemos decir que queremos que las filas sean dictionaries, en vez de tuplas, de manera que podemos acceder a los campos usando el nombre del campo, en vez de un índice. Para ello, basta con obtener el cursor de esta manera

conn = MySQLdb.connect (…)
cursor = conn.cursor(MySQLdb.cursors.DictCursor)

y así podemos acceder a los campos a través de su nombre

cursor.execute("select * from tabla")
fila = cursor.fecthone()
# para acceder a uno de los campos
print fila["nombre_columna"]

Una tontería, pero estoy acostumbrado a java y a C++ y no a lenguajes tan flexibles.

 

Apr 23

Python: Una de cal y una de arena

Sé que "una de cal y una de arena" significa una cosa buena y una cosa mala. El problema es que nunca he sabido si la cal es la mala, la arena la buena o a la viceinversa.

Hace tiempo comenté que iba a hacer una pequeña aplicación web en python para pedirle a la gente que metiera cada mes el tiempo que dedica a cada uno de los proyectos, de forma que luego sacara en excel una tabla con dichos tiempos. Pues bien, ya está hecha (un poco de aquella manera) y funcionando. Así que tras esta mínima experiencia con python, ahí van un par de impresiones, una buena y otra mala, una de cal y otra de arena.

La cosa mala: Me da la impresión, al igual que casi todos los lenguajes de script en los que defines las cosas sobre la marcha, que python es un lenguaje muy difícil de mantener. Al no definirse claramente los tipos, cuando en una función o método recibes parámetros, no tienes ni idea de lo que recibes, salvo que lo pongas muy bien comentado. De hecho, en eclipse con el plugin pydev para programar en python, el autocompletar que te muestra los nombres de atributos y métodos de las clases, eclipse sólo te puede mostrar aquellos atributos y clases que hayas usado previamente en el código.

En java, por ejemplo, hay que declararlo todo, por lo que en cualquier momento sabes cada variable de qué tipo es y qué cosas tiene o a las que puedes llamar. No dependes (salvo para entenderlo mejor) de que el programador se haya acordado de comentar adecuadamente el código.

La cosa buena: Precisamente esta falta de tipado y el poder meter una manzana donde se espera un higo me da la impresión que hace de python un lenguaje muy flexible, y pongo un ejemplo. Puesto que mi aplicación es web, en casi todos los métodos/funciones que he hecho recibo de parámetro un Request Object, que el mismo servidor web se encarga de pasarme y con el que tengo acceso a los parámetros de la petición http, con el que puedo escribir los tag html que se verán en el navegador, etc. Pues bien, para mis pruebas sin servidor web desde eclipse, me hice una clase MiClase con un método write() similar al de Request Object, lo instancié y llamé a mis métodos a pelo pasándoles una instancia de MiClase. El código "tragó" con eso perfectamente, y la salida html salía por donde decía MiClase, es decir, por pantalla normal.

En otros lenguajes como java habría sido necesario heredar del objeto en cuestión y sobreescribir los métodos necesarios, quizás incluso declarar un constructor obligatorio con los parámetros raros que tuviera la clase padre. En java es aconsejable el uso de interfaces precisamente por este motivo, para poder cambiar una cosa por otra sin "cargar" con la clase original heredando de ella. En python no hacen falta interfaces. Basta con que la clase sustituta tenga los métodos que se usen de la clase original.

Todo esto me hace preguntarme si lo del desarrollo rápido de lenguajes como python se refiere a que no es necesario declarar los tipos (desde luego, eso ahorra tiempo, pero me parece un tiempo mínimo respecto a todo el proceso o el tiempo que puedes perder en depuración mientras decides si una variable es de un tipo u otro), o bien se debe a esta flexibilidad del lenguaje, que permite mezclar churras con merinas y todo funciona como debe.