Capítulo 4. El poder de la introspección

Este capítulo trata uno de los puntos fuertes de Python: la introspección. Como usted sabe, todo en Python es un objeto, y la introspección es código que ve otros módulos y funciones en memoria como objetos, obtiene información sobre ellos y los manipula. De paso, definiremos funciones sin nombre, llamaremos a funciones con argumentos sin el orden establecido, y haremos referencia a funciones cuyos nombres incluso desconocemos.

4.1. Inmersión

Aquí hay un programa en Python completo y funcional. Debería poder comprenderlo en gran parte sólo observándolo. Las líneas numeradas ilustran conceptos cubiertos en el Capítulo 2, Su primer programa en Python. No se preocupe si el resto del código le parece inquietante; aprenderá todo sobre él en este capítulo.

Ejemplo 4.1. apihelper.py

Si aún no lo ha hecho, puede descargar éste ejemplo y otros usados en este libro.


def info(object, spacing=10, collapse=1): 1 2 3
    """Imprime métodos y cadenas de documentación.
    
    Toma un módulo, clase, lista, diccionario o cadena."""
    methodList = [method for method in dir(object) \
                       if callable(getattr(object, method))]
    processFunc = collapse and \
                       (lambda s: " ".join(s.split())) or (lambda s: s)
    print "\n".join(["%s %s" %
                      (method.ljust(spacing),
                       processFunc(str(getattr(object, method).__doc__)))
                     for method in methodList])

if __name__ == "__main__":                4 5
    print info.__doc__
1 Este módulo tiene una funcion, info. Según su declaración admite tres parámetros: object, spacing y collapse. Los dos últimos son en realidad parámetros opcionales, como veremos en seguida.
2 La función info tiene una cadena de documentación de varias líneas que describe sucintamente el propósito de la función. Advierta que no se indica valor de retorno; esta función se utilizará solamente por sus efectos, no por su valor.
3 El código de la función está sangrado.
4 El truco if __name__ permite a este programa hacer algo útil cuando se ejecuta aislado, sin que esto interfiera para que otros programas lo usen como módulo. En este caso, el programa simplemente imprime la cadena de documentación de la función info.
5 Las sentencias if usan == para la comparación, y no son necesarios los paréntesis.

La función info está diseñada para que la utilice usted, el programador, mientras trabaja en el IDE de Python. Toma cualquier objeto que tenga funciones o métodos (como un módulo, que tiene funciones, o una lista, que tiene métodos) y muestra las funciones y sus cadenas de documentación.

Ejemplo 4.2. Ejemplo de uso de apihelper.py

>>> from apihelper import info
>>> li = []
>>> info(li)
append     L.append(object) -- append object to end
count      L.count(value) -> integer -- return number of occurrences of value
extend     L.extend(list) -- extend list by appending list elements
index      L.index(value) -> integer -- return index of first occurrence of value
insert     L.insert(index, object) -- insert object before index
pop        L.pop([index]) -> item -- remove and return item at index (default last)
remove     L.remove(value) -- remove first occurrence of value
reverse    L.reverse() -- reverse *IN PLACE*
sort       L.sort([cmpfunc]) -- sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1

Se da formato por omisión a la salida para que sea de fácil lectura. Las cadenas de documentación de varias líneas se unen en una sola línea larga, pero esta opción puede cambiarse especificando 0 como valor del argumento collapse. Si los nombres de función tienen más de 10 caracteres, se puede especificar un valor mayor en el argumento spacing para hacer más legible la salida.

Ejemplo 4.3. Uso avanzado de apihelper.py

>>> import odbchelper
>>> info(odbchelper)
buildConnectionString Build a connection string from a dictionary Returns string.
>>> info(odbchelper, 30)
buildConnectionString          Build a connection string from a dictionary Returns string.
>>> info(odbchelper, 30, 0)
buildConnectionString          Build a connection string from a dictionary
    
    Returns string.