jueves, 5 de febrero de 2009

Imports de Python como en Java

En Java, si tenemos 2 directorios con fuentes, y en cada directorio una misma estructura de paquetes, la JVM se encarga automáticamente de buscar cada clase/paquete en los distintos directorios. Por ejemplo, podemos tener src1 y src2 en el classpath, cada directorio con los mismos paquetes:

src1/ar/com/ejemplo/Uno.java
src2/ar/com/ejemplo/Dos.java


Desde una clase podemos hacer referencias a Uno y Dos sin mayores problemas, por ejemplo:

import ar.com.ejemplo.Uno;
import ar.com.ejemplo.Dos;


Pero con Python esto se complica y no funciona automáticamente. Si tenemos src1 y src2 en el PYTHONPATH, cada directorio con estructura similar:

src1/__init__.py
src1/ejemplo/__init__.py
src1/ejemplo/uno.py

src2/__init__.py
src2/ejemplo/__init__.py
src2/ejemplo/dos.py


Con PYTHONPATH=src1:src2

from ejemplo import uno -> importa OK
from ejemplo import dos -> ImportError


Con PYTHONPATH=src2:src1

from ejemplo import uno -> ImportError
from ejemplo import dos -> importa OK


Esto se puede solucionar utilizando pkgutil, modificando src1/ejemplo/__init__.py y src2/ejemplo/__init__.py de forma que incluya:

from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)


De esta manera, usando "extend_path" logramos lo que buscábamos, independientemente del orden en que están src1 y src2 en el PYTHONPATH.

from ejemplo import uno -> importa OK
from ejemplo import dos -> importa OK

No hay comentarios: