Entries for Python

Simular enumeraciones en Python

written by uve

14 May 2012

Estoy ahora mismo trabajando con Python y me acabo de encontrar que disponer de una enumeración me vendría muy bien. Así que, después de investigar un rato, he encontrado dos formas distintas y muy prácticas para hacer enumeraciones.

Estilo C

La primera opción, es hacerlas como se hacen en C. Variables enteras globales:

(GATEWAY_CLASS, FORWARDING_CLASS, PARSE_CLASS) = range(1, 4)

El problema de esta solución, es que en cualquier momento se puede modificar el valor de cualquiera de estas variables, con las consecuencias que esto conlleva.

Estilo Java

En Java, cuando declaramos una enumeración, debemos acceder a través del nombre de la enumeración. Por tanto, para simular este comportamiento en Python, necesitamos una clase:

class RoutingClassType(type):
    (GATEWAY_CLASS,
        FORWARDING_CLASS,
        PARSE_CLASS) = range(1, 4)

Así, ahora tendríamos que acceder así:

RoutingClassType.GATEWAY_CLASS

Aunque esta solución sigue presentando el mismo problema que la solución anterior, lo podemos solucionar creando un nuevo tipo que impida modificar sus atributos:

class EnumType(type):
    def __setattr__(self, name, value):
        raise ValueError

Y ahora bastará con definir nuestra enumeración de la siguiente forma:

class RoutingClassType(type):
    __metaclass__ = EnumType
   
    (GATEWAY_CLASS,
        FORWARDING_CLASS,
        PARSE_CLASS) = range(1, 4)

Full entry >>

SystemError: error return without exception set

written by uve

11 April 2012

Esto se puede deber a que se ha devuelto NULL en una función en la que se debería devolver algo (None por ejemplo):

static PyObject*
example(PyObject *self, PyObject* args, PyObject* kwargs)
{
    // do something
    return NULL;
}

se corrige de la siguiente forma:

static PyObject*
example(PyObject *self, PyObject* args, PyObject* kwargs)
{
    // do something
    Py_RETURN_NONE;
}

o porque al lazar una excepción, no hemos indicado de que excepción se trata:

static PyObject*
example(PyObject *self, PyObject* args, PyObject* kwargs)
{
    PyObject* var;
    // ...
    if(!PyBool_Check(var))
    {
        return NULL;
    }
}

y se corrige:

static PyObject*
example(PyObject *self, PyObject* args, PyObject* kwargs)
{
    PyObject* var;
    // ...
    if(!PyBool_Check(var))
    {
        PyErr_SetString(PyExc_TypeError, "Not boolean");
        return NULL;
    }
}

Full entry >>

Bindings Python para bibliotecas C: Argumentos (Parte 4)

written by uve

28 March 2012

Continuando con el ejemplo de ayer, hoy voy a explicar cómo podemos parsear los parámetros de entrada. El estado actual es que hemos definido unos prototipos y los hemos añadido al módulo. Ahora vamos a darle contenido a las funciones add y hello.

Ejemplo en GitHub: mema_methods.

Full entry >>

Argumentos en Python

written by uve

28 March 2012

Para los programadores de C, C++, Java, ... puede resultar un tanto extraño la forma de gestionar los parámetros que tiene Python.

Voy a explicar en esta entrada los tipos de parámetros y cómo podemos hacer uso de ellos.

Full entry >>

Bindings Python para bibliotecas C: Métodos (Parte 3)

written by uve

27 March 2012

Ayer explicaba cómo se monta una estructura básica para crear un módulo. Pero para que el módulo sirva para algo, tendremos que añadir funciones.

Ahora vamos a ver cómo podemos crear nuevas funciones y cómo integrarlas al módulo mema. El objetivo para hoy será crear dos funciones: hello y add.

El resultado debería ser algo similar a lo siguiente:

>>> import mema
>>> mema.hello()
Hello mema!
>>> mema.hello('Vicente')
Hello Vicente!
>>>
>>> from mema import add
>>> add(1, 2)
3
>>> add(400, 4)
404
>>>

Ejemplo en GitHub: mema_methods.

Full entry >>

Bindings Python para bibliotecas C: Módulos y compilación (Parte 2)

written by uve

26 March 2012

La semana pasada empecé ha hablar sobre los Bindings en Python. Hoy vamos a ver cómo es una estructura muy básica, cómo compilar y probar que todo funciona.

Un problema que me estoy encontrando, es que el API C de Python ha ido cambiando con las versiones. Entonces, muchos ejemplos que he encontrado no compilan y hay código muy diferente por ahí.

Inicialmente voy a centrarme en Python 2.7 (última versión de la rama 2.x) y si encuentro tiempo, haré lo mismo para Python 3.

Ejemplo en GitHub: mema_bare.

Full entry >>

Bindings Python para bibliotecas C: ¿Qué son? (Parte 1)

written by uve

23 March 2012

Hoy voy a hablar acerca de bindings para Python. Un binding es un módulo Python, escrito en lenguaje C, que permite realizar llamadas a funciones en C desde un script hecho en Python. Se puede ver como un "puente" desde C a Python.

Pueden existir distintos motivos para desear hacer un binding. En principio, puede parecer un poco contraproducente, ya que se pierde portablidad

Entonces, ¿por qué crear un binding? Bien es sabido por todos que C es más eficiente que Python, por tanto, si se trata de una parte crítica de una aplicación, perfectametne se puede hacer el procesamiento en C y dejar Python para la lógica.

Otra razón es aprovechar código existente en C. Como comenté, estoy trabajando en libemqtt, la cuál está escrita en C. Podría hacer una nueva implementación completa en Python, pero teniendo el código disponible, lo lógico es hacer un binding.

Los próximos días intentaré escribir una pequeña guía sobre cómo hacer un binding para esta bibliotecta.

Actualización (27/03/2012): He creado un repositorio en GitHub con los ejemplos que estoy implementando:

https://github.com/menudoproblema/menudoproblema-examples/tree/master/python/bindings

Full entry >>

Validación de NIFs y CIFs en Python 3

written by uve

24 February 2012

Hace más de un año escribí un par de entradas acerca de cómo realizar la validación de NIFs y CIFs en Python. He adaptado ese código para Python 3k y modificado un par de detalles.

Full entry >>

OnlyGL

written by uve

2 February 2012

Últimamente he estado bastante liado, entre el trabajo, la carrera y el máster apenas tengo tiempo para escribir.

Como resultado de unas prácticas de una asignatura, Diseño Asistido por Computador, he desarrollado un pequeño Framework en Python con OpenGL cuyo objetivo es desarrollar escenas 3D de forma rápida y sencilla. En unas pocas líneas de código podemos ver los resultados rápidamente.

He liberado el código fuente del Framework y está disponible en GitHub: OnlyGL. Aunque en principio no tengo intención de seguir evolucionando OnlyGL, acepto sugerencias y no tengo problema en invertir algún tiempo si alguien está interesado en algo concreto.

Full entry >>

Capturar señales en Python

written by uve

9 December 2011

A continuación dejo un pequeño ejemplo de como se pueden capturar señales con Python:

import signal
import time
import sys

def signal_handler(sig, func=None):
    print 'SignalHandler. Saliendo...'
    sys.exit(0)

if __name__=='__main__':
    signal.signal(signal.SIGTERM, signal_handler)

    print 'Esperando 15 segundos...'
    time.sleep(15)
    print 'Finalizado'

La idea es muy simple, el programa espera 15 segundos y finaliza. Si se envía la señal SIGTERM (señal 15) el proceso terminará sin esperar. Veamos como se ejecuta de forma normal:

$ python test.py 
Esperando 15 segundos...
Finalizado

Y aquí podemos ver cómo se capturan las señales y se finaliza antes el proceso:

$ python test.py &
[1] 8172
Esperando 15 segundos...
$ kill -15 8172
SignalHandler. Saliendo...
[1]+  Hecho                   python test.py
$

Full entry >>

Analizar los parámetros de consulta de URL en Python

written by uve

11 August 2011

>>> from urlparse import urlparse
>>> url = urlparse('http://www.google.com/search?client=ubuntu&channel=fs&q=python')
>>> params = dict([part.split('=') for part in url[4].split('&')])
>>> params
   {'channel': 'fs', 'client': 'ubuntu', 'q': 'python'}

Full entry >>

Soporte para JPEG, Zlib y FreeType2 en PIL

written by uve

26 April 2011

Hace unos días escribía como Compilar PIL dentro de VirtualEnv, pero realicé la compilación sin soporte para JPEG, Zlib o FreeType2. Ahora mismo estaba probando un script y me he encontrado el siguiente error:

ImportError: The _imagingft C module is not installed

Este error se debe a que no hay soporte para FreeType2. Revisando el directorio de instalación (donde están los fuentes) me he econtrado con lo siguiente:

--------------------------------------------------------------------
PIL 1.1.7 SETUP SUMMARY
--------------------------------------------------------------------
version       1.1.7
platform      linux2 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53)
              [GCC 4.5.2]
--------------------------------------------------------------------
*** TKINTER support not available
*** JPEG support not available
*** ZLIB (PNG/ZIP) support not available
*** FREETYPE2 support not available
*** LITTLECMS support not available
--------------------------------------------------------------------

Al final he optado por la solución más sencilla. Instalarlo en el sistema y utilizarlo dentro de VirtualEnv. Para ello:

$ cd /path/to/virtualenv
$ ln -s /usr/lib/python2.7/dist-packages/PIL/ lib/python2.7/site-packages/

Full entry >>

Instalando PIL dentro de VirtualEnv

written by uve

20 April 2011

A la hora de instalar PIL dentro de VirtualEnv me he encontrado con el siguiente problema:

(ENV)~/ENV$ easy_install pil    
Searching for pil
Reading http://pypi.python.org/simple/pil/
Reading http://www.pythonware.com/products/pil
Reading http://effbot.org/zone/pil-changes-115.htm
Reading http://effbot.org/downloads/#Imaging
Best match: PIL 1.1.7
Downloading http://effbot.org/media/downloads/PIL-1.1.7.tar.gz
Processing PIL-1.1.7.tar.gz
Running PIL-1.1.7/setup.py -q bdist_egg --dist-dir /tmp/easy_install-3H1mTt/PIL-1.1.7/egg-dist-tmp-eVNOlg
WARNING: '' not a valid package name; please use only.-separated package names in setup.py
_imaging.c:75:20: fatal error: Python.h: No existe el fichero o el directorio
compilation terminated.
error: Setup script exited with error: command 'gcc' failed with exit status 1

El problema radica en que PIL es que parte está escrita en C, por lo que es necesario compilarlo previamente.

Full entry >>

Generar un fichero XML con DOM

written by uve

6 April 2011

Ayer hablaba un poquito en general acerca de distintos tipos de interfazces para parsear documentos XML. Hoy he preparado un par de ejemplos de como generar un documento XML.

Los ejemplos están hechos en Python, el cuál es ideal para mostrar su funcionamiento. Esto se debe a que Python incluye en su librería estándar un módulo xml, por lo que no es necesario instalar nada extra. Además he utilizado el módulo xml.dom.minidom. minidom es una implementación ligera de la interfaz DOM, cuyo objetivo es ser más rápido y ligero.

Los ejemplos están disponibles aquí.

Full entry >>

Parsear una web con sax y python directamente

written by uve

4 April 2011

Para quien no lo conozca, SAX es una interfaz parsear XML y está disponible en la librería estándar de Python. Últimamente estoy trabajando mucho con parsers XML, así que si el tiempo lo permite escribiré algún artículo más sobre el tema.

Para parsear una url, sin necesidad de descargarla previamente y luego parsearla, podemos apoyar el parser, xml.sax, en urllib2:

import urllib2
import xml.sax

class MiHandler(xml.sax.ContentHandler):
    def startElement(self, name, attrs):
        print name

parser = xml.sax.make_parser()
parser.setContentHandler(MiHandler())
feed = urllib2.urlopen("http://www.menudoproblema.es/feeds/latest/")
parser.parse(feed)

Full entry >>

La teoría es cuando crees saber algo, pero no funciona.
La práctica es cuando algo funciona, pero no sabes por qué.
Los programadores combinan la teoría y la práctica:
Nada funciona y no saben por qué.