jueves, marzo 26, 2009

Invertir una cadena

Ayer tenía que invertir una cadena y no me acordaba exactamente como hacerlo. Si tenía string un metodo para ello o no...
Pero tenía la problemática de que estaba con python 2.3. Bueno... al lio.

En python 2.3 NO puedes hacer:


>>> s = "0123456789"
>>> "".join(reversed(s))
'9876543210'


Pero si:


>>> s[::-1]
'9876543210'


Pongo alguna invocación mas de slicings, para entenderlo:


>>> s[::]
'0123456789'
>>> s[3::]
'3456789'
>>> s[:3:]
'012'
>>> s[::3]
'0369'
>>> s[::-2]
'97531'
>>> s[-2::-2]
'86420'

martes, marzo 17, 2009

Recopilando web semantica

Al igual que he hecho con temas lingüísticos voy a hacer lo mismo con lo de la web semantica. De delicious:


Del blog:

Recopilado info lingüistica

Ayer estuve echando un vistazo a mis cosillas tageadas en delicious, en relación con la lingüistica, NERs, ... Ahí van:

Un día me debería poner a organizar un poquillo los tags.
En cuanto a este blog, los que hay relacionados:
Esta recopilación viene a colación de que estuve buscando que productos ahi sobre NER. El sitio con mas info es la wikipedia. De hecho no he sido capaz de encontrar info en mas sitios (en el rato que estuve buscando).
De lo que miré me ha sorprendido FreeLing. Espero poder probarlo en breve...

martes, marzo 10, 2009

Anonymous Code Blocks in Python

Siguiendo con la tónica de los ultimos posts, ahí va una mas, para simplemente enlazar un artículo muy interesante: Exploring Dynamic Scoping in Python.

En el, el autor, logra crear 'code blocks' anónimos.
Gracias a leer este artículo se me ha ocurrido que podemos crear dinámicamente funciones, pero eso ya será para otro post....
Autonota de que usar:


code(argcount, nlocals, stacksize, flags, codestring,
constants, names, varnames, filename, name,
firstlineno, lnotab[, freevars[, cellvars]])
function(code, globals[, name[, argdefs[, closure]]])


Hoy curiosamente llego por segunda vez a BytePlay.

Decompiling with introspection

Ultimamente he estado jugando con decompyle. Necesitaba obtener código que estaba generado con python 2.3, con lo cual por ese lado no tenía ningun problema.
El problema es que no disponía ni siquiera del código fuente, los módulos estaban embebidos en el interprete. ¿Ingenioso verdad? ¿Que hacer ante esto? Pues fácil. A tirar de introspección y a generar el código de los CodeObject encontrados.

Para generar el código sin tener que tocar decompyle, usé la siguiente función:



def decompile(codeObject):
"""
Método que realiza la decompilación
"""

# decompyle, funciona volcando a un archivo o a stdout.
# Para no modificar el código de decompyle, hemos hecho la ñapa
# de usar un fichero temporal.

code = None
fout = None
tmpFile = None
try:
try:
to_avoid = ['# local variables:','# tab-width:','# emacs-mode:'] # Esto lo genera decompile

tmpHandle,tmpFile = tempfile.mkstemp()
os.close(tmpHandle)
fout = open(tmpFile,"w+")
decompyle.decompyle("2.3", codeObject, fout, 0, 0)
fout.seek(0,0)
lines = []
for line in fout:
skip = False
for item in to_avoid:
if line.find(item) != -1:
skip = True
break
if not skip: lines.append(line)
code = "".join(lines)
except:
pass
finally:
# En python 2.3 el finally no se puede mezclar con un un 'try' normal
if fout is not None: fout.close()
if tmpFile is not None: os.remove(tmpFile)

return code




Mediante una lista de módulos a decompilar, y usando el módulo inspect, podemos llegar al código de las funciones, métodos.
El resto de código tendremos que generarlo nosotros (*1). Y aún así nunca podremos llegar a generar el código original, pero bueno... en plan de tener algo de documentación, pues bien está...

¿porque digo esto último? Porque al ir tirando de una lista de módulos que se van cargando, vamos a ir haciendo introspección de sus atributos: tipos basicos, módulos, clases....
En principio, el script que yo hice va dirigido por módulos, es decir, no va profundizando en los módulos, ya que no te puedes fiar, ya que los import, te van a generar un elemento en el espacio de nombres del módulo que estas analizando.

Otro ejemplo lo tenemos con las clases. Si tienemos un import tal que 'from mimodulo import clasecita', nos vamos a encontrar que 'clasecita' en el contexto de decompilación actual y vamos a intentar obtener su código, cuando dicha clase realmente está definida en otro módulo.

(*1) Toda la estructura de ficheros, clases, funciones, ... hay que generarla a pelo.

lunes, marzo 02, 2009

Decompilando built-ins

Si disponemos de código python 2.3 en principio, usando decompyle, es posible obtener el código fuente.
Pero... ¿que pasa si el código que queremos compilar es código python pero está embebido en el interprete que estamos usando? Pues que también podemos obtenerlo... Al menos de las funciones. Para ello necesitamos usar un módulo que acabo de descubrir, inspect.

Adjunto un ejemplo de como lo he usado, para decompilar el código de una función (en el ejemplo Document es un módulo built-in):

import inspect
import decompyle
import sys


#--- Módulo
#members = inspect.getmembers(Document)
#for member in members:
# print member

#--- Documento
d = Document.Document("a")
#members = inspect.getmembers(d)
#for member in members:
# print member

#--- Método => Función
#print "Método"
members = inspect.getmembers(d.SetLogger)
im_func = None
for member in members:
if member[0] == 'im_func':
im_func = member[1]

if im_func == None:
raise Exception,"No se ha podido obtener la función para el mètodo."


# Fúnción => Code Object
print "Función"
members = inspect.getmembers(im_func)
func_code = None
for member in members:
if member[0] == 'func_code':
func_code = member[1]


if func_code is None:
raise Exception,"No se ha podido obtener el 'code_object' para la función."

#print type(func_code)

decompyle.decompyle("2.3", func_code, sys.stdout, 0, 0)