Problema con la ruta de búsqueda del módulo Python

Estoy tratando de trabajar en un entorno de desarrollo, pero parece que hay problemas porque Python está usando módulos del directorio site-packages. Quiero que esté usando los módulos de mi directorio dev.

sys.path devuelve un montón de dirs, como este

['', '/usr/lib/python26.zip', '/usr/lib/python2.6', '/usr/lib/python2.6/plat-linux2', '/usr/lib/python2.6/lib-tk', '/usr/lib/python2.6/lib-old', '/usr/lib/python2.6/lib-dynload', '/usr/lib/python2.6/site-packages' etc 

Esto es bueno, está usando el directorio actual como el primer lugar de búsqueda (al menos así es como lo entiendo).

Bien, ahora si creo un archivo llamado command.py en el directorio actual, las cosas funcionan como yo las esperaría.

 >>> import commands >>> commands.__file__ 'commands.pyc' 

Luego salgo de la shell de python y empiezo otra. Entonces hago esto.

 >>> import foo.bar.commands 

Ahora, lo que espero que haga es bajar del directorio actual a ./foo/bar/ y obtener el módulo de comandos desde allí. Lo que recibo es esto

 >>> foo.bar.commands.__file__ '/usr/lib/python2.6/site-packages/foo/bar/commands.pyc' 

Aunque desde mi directorio actual hay un archivo ./foo/bar/commands.py

Usando imp.find_module () y imp.load_module () puedo cargar el módulo local correctamente. Lo que es realmente interesante (aunque realmente no sé lo que significa) es la última línea que se imprime en esta secuencia

 >>> import foo.bar.commands >>> foo.bar.commands.__file__ '/usr/lib/python2.6/site-packages/foo/bar/commands.pyc' >>> foo.bar.__file__ '/usr/lib/python2.6/site-packages/foo/bar/__int__.pyc' >>> foo.__file__ './foo/__init__.pyc' 

Entonces, si puede encontrar foo / init .pyc en el directorio local, ¿por qué no puede encontrar los otros archivos en el directorio local?

Aclamaciones

Menciona que hay un directorio foo en su directorio actual, pero no nos dice si foo/__init__.py existe (incluso posiblemente vacío): si no lo hace, esto le dice a Python que foo no es un paquete. De manera similar para foo/bar/__init__.py – si ese archivo no existe, incluso si foo/__init__.pyfoo/__init__.py , entonces foo.bar no es un paquete.

Puedes jugar un poco colocando archivos .pth y / o configurando __path__ explícitamente en tus paquetes, pero la regla básica y simple es colocar un __init__.py en cada directorio que quieras que Python reconozca como un paquete. El contenido de ese archivo es “el cuerpo” del propio paquete, por lo que si import foo y foo es un directorio con un archivo foo/__init__.py , entonces eso es lo que está importando (en cualquier caso, el cuerpo del paquete se ejecuta) la primera vez que importe algo del paquete o cualquier subpaquete del mismo).

Si ese no es el problema, parece que otra importación (o manipulación explícita de sys.path) puede estar causando problemas. La ejecución de python con un indicador -v hace que las importaciones sean altamente visibles, lo que puede ayudar. Otra buena técnica es colocar un

 import pdb; pdb.set_trace() 

justo antes de la importación que cree que se está comportando mal, y al examinar sys.path, sys.modules (y posiblemente otras estructuras avanzadas como los ganchos de importación) en ese punto, ¿hay un sys.modules [‘foo’] ya definido, por ejemplo? ? También puede resultar instructivo probar de forma interactiva las funciones del módulo de biblioteca estándar imp que ubicar módulos en su nombre, dada una ruta.

¿Qué está haciendo foo en /usr/lib/python2.6/site-packages? Parece que ha creado foo en su directorio local pero no es necesariamente el que está importando.

Intenta deshacerte de foo / bar en los paquetes de sitio

Asegúrate de que la estructura de tu directorio se vea así.

 /foo/__init__.py /bar/__init__.py /commands.py 

Además, es una buena idea no reutilizar los nombres de la biblioteca estándar de Python para sus propios módulos. ¿Puede llamar a los comandos.py alguna otra cosa?