2.4. Obtención de referencias a objetos con getattr

Ya sabe usted que las funciones de Python son objetos. Lo que no sabe es que se puede obtener una referencia a una función sin necesidad de saber su nombre hasta el momento de la ejecución, utilizando la función getattr.

Ejemplo 2.11. Presentación de getattr

>>> li = ["Larry", "Curly"]
>>> li.pop                       1
<built-in method pop of list object at 010DF884>
>>> getattr(li, "pop")           2
<built-in method pop of list object at 010DF884>
>>> getattr(li, "append")("Moe") 3
>>> li
["Larry", "Curly", "Moe"]
>>> getattr({}, "clear")         4
<built-in method clear of dictionary object at 00F113D4>
>>> getattr((), "pop")           5
Traceback (innermost last):
  File "<interactive input>", line 1, in ?
AttributeError: 'tuple' object has no attribute 'pop'
1 Así se obtiene una referencia al método pop de la lista. Observe que no se llama al método pop; la llamada sería li.pop(). Esto es el método en sí.
2 Aquí también se devuelve una referencia al método pop, pero esta vez el nombre del método se especifica como una cadena, argumento de la función getattr. getattr es una función incorporada increíblemente útil que devuelve cualquier atributo de cualquier objeto. En este caso, el objeto es una lista, y el atributo es el método pop.
3 Si no le ha impresionado aún la increíble utilidad de esta función, intente esto: el valor de retorno de getattr es el método, que puede ser llamado igual que si se hubiera puesto directamente li.append("Moe"). Pero no se ha llamado directamente a la función; en lugar de esto, se ha especificado su nombre como una cadena.
4 getattr también funciona con diccionarios.
5 En teoría, getattr debería funcionar con tuplas, pero como las tuplas no tienen métodos, getattr lanzará una excepción sea cual sea el nombre de atributo que se le dé.

getattr no sirve sólo para tipos de datos incorporados. También funciona con módulos.

Ejemplo 2.12. getattr en apihelper.py

>>> import odbchelper
>>> odbchelper.buildConnectionString             1
<function buildConnectionString at 00D18DD4>
>>> getattr(odbchelper, "buildConnectionString") 2
<function buildConnectionString at 00D18DD4>
>>> object = odbchelper
>>> method = "buildConnectionString"
>>> getattr(object, method)                      3
<function buildConnectionString at 00D18DD4>
>>> type(getattr(object, method))                4
<type 'function'>
>>> import types
>>> type(getattr(object, method)) == types.FunctionType
1
>>> callable(getattr(object, method))            5
1
1 Esto devuelve una referencia a la función buildConnectionString del módulo odbchelper, que estudiamos en Conozcamos Python. (La dirección hexadecimal que se ve es específica de mi máquina; la suya será diferente).
2 Utilizando getattr, podemos obtener la misma referencia para la misma función. En general, getattr(objeto, "atributo") es equivalente a objeto.atributo. Si objeto es un módulo, entonces atributo puede ser cualquier cosa definida en el módulo: una función, una clase o una variable global.
3 Y esto es lo que realmente utilizamos en la función help. object se pasa como argumento de la función; method es una cadena que contiene el nombre de un método o una función.
4 En este caso, method es el nombre de una función, lo que podemos comprobar obteniendo su tipo con type.
5 Como method es una función, se puede llamar.