2009-12-04 10 views
12

Por ejemplo, quiero hacer un plugin sql alquimia para otro proyecto. Y quiero nombrar ese módulo sqlalchemy.py. El problema con esto es que no me permite importar sqlalchemy:¿Cómo puedo evitar que un módulo de Python se importe solo?

#sqlalchemy.py 
import sqlalchemy 

Esto hará que el propio módulo de importación. He intentado esto, pero parece que no funciona:

import sys 
#Remove the current directory from the front of sys.path 
if not sys.path[0]: 
    sys.path.pop(0) 
import sqlalchemy 

¿Alguna sugerencia?

+1

Cosa curiosa, obtuve el resultado inverso hace un momento al hacer un 'de {algo} importar {algo}' – MitMaro

+0

No estoy del todo claro sobre lo que estás tratando de hacer. ¿Es para 'sombrear' el módulo 'sqlalchemy' real con el suyo, de modo que otros módulos que intentan importar' sqlalchemy' obtengan el suyo en su lugar, pero (solo) el suyo puede obtener el 'sqlalchemy' real? –

+0

No, es un submódulo de un paquete más grande. Da la casualidad de que Python parece elegir la importación relativa antes de la importación absoluta. –

Respuesta

12

Editar: como el OP se ha mencionado que el tema es uno de importación relativa prefiriéndose a absoluta, la solución más sencilla para el problema específico de la OP es añadir al comienzo del módulo from __future__ import absolute_import que cambia que "la preferencia "/ ordenando.

El siguiente todavía se aplica a la cuestión delicada de dos chocando importaciones en términos absolutos (que no parece ser lo que el PO se enfrenta actualmente ...):

Una vez que haya importado un módulo denominado x, ese módulo está registrado en sys.modules['x'] - cambiar sys.path como lo está haciendo no alterará sys.modules. También deberá modificar sys.modules directamente.

por ejemplo, tener en cuenta:

$ cat a/foo.py 
print __file__; import sys; sys.path.insert(0, "b"); del sys.modules["foo"]; import foo 
$ cat b/foo.py 
print __file__ 
$ python2.5 -c'import sys; sys.path.insert(0, "a"); import foo' 
a/foo.py 
b/foo.py 

(a correr de nuevo va a usar y mostrar los archivos .pyc en lugar de los .py, por supuesto).

No es el enfoque más limpio, y por supuesto, el módulo foo original es, inevitablemente, no accesible desde el exterior (ya que su entrada sys.modules ha sido desplazada), pero se pueden jugar trucos más frágiles según sea necesario (oculte sys.modules["foo"] en algún lugar antes de eliminarlo, después de importar el otro foo ponga ese módulo en otro lugar y restablezca el sys.modules["foo"] original, etc., dependiendo de sus necesidades exactas. (Por supuesto, evitar el nombre de enfrentamientos en primer lugar casi invariablemente sería más sencillo que bailar vals a su alrededor de esta manera ;-).

+0

En realidad, 'sys.modules ['sqlalchemy']' apunta al sqlalchemy real. 'sys.modules ['storm.databases.sqlalchemy']' apunta a mi módulo. Da la casualidad de que Python parece elegir la importación relativa sobre la importación absoluta. –

+1

@Jason, sí, a menos que 'de __future__ import absolute_import', que es la solución más simple cuando el problema es de importaciones relativas frente a absolutas (mi respuesta aún se recomienda para importaciones absolutas conflictivas). Déjame editar la respuesta en consecuencia. –

+0

Lo siento, debería haber sido más claro en mi pregunta. :-) ¿Qué versión de Python es compatible con '__future__'? –

3

¿No lo nombras sqlalchemy.py?

En serio. Creo que este es el problema que se supone que soluciona la importación absoluta. En python 2.5 no debería suceder, pero podría estar equivocado

+0

Podría hacerlo, pero el proyecto carga dinámicamente plugins por nombre de módulo. No es preferible, pero está un poco fuera de mis manos. –

+0

Sucede bajo Python 2.6.4. No lo he probado en otras versiones. –

2

Puede que te quemen las diferencias entre el código que se ejecuta en el intérprete interactivo y el de un archivo. Elimine la prueba de sys.path[0] que está vacía (cuando se ejecuta desde un archivo, no lo está) y la importación debería funcionar ahora como lo desee.

$ more sqlalchemy.py 
import sys 
print sys.path[0] 
sys.path.pop(0) 
import sqlalchemy 
print sqlalchemy.__file__ 
$ python sqlalchemy.py 
/Users/nad 
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/sqlalchemy/__init__.pyc 
$ python 
Python 2.6.4 (r264:75706, Oct 28 2009, 20:34:51) 
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import sys; print repr(sys.path[0]) 
'' 

EDIT: Lo anterior se aplica si su módulo principal es sqlalchemy.py. Si su módulo es importado por otro módulo, también deberá modificar sys.modules como lo explica Alex.

Cuestiones relacionadas