2009-07-08 8 views
13

Supongamos que hay una carpeta, '/ home/user/temp/a40bd22344'. El nombre es completamente aleatorio y cambia en cada iteración. Necesito poder importar esta carpeta en Python usando un nombre fijo, digamos 'proyecto'. Sé que puedo agregar esta carpeta a sys.path para habilitar la búsqueda de importación, pero ¿hay alguna manera de reemplazar 'a40bd22344' por 'project'?Anular espacio de nombre en Python

Tal vez algunos hacks inteligentes en init .py?

Agregado:

Tiene que ser global - es decir, otros scripts que cargan 'proyecto' a través del estándar:

import project 

tienen que trabajar adecuadamente, cargando a40bd22344 lugar.

+1

¿Por qué no puede arreglar el proceso que creó el archivo temporal? Sería más fácil arreglar esto en la fuente en lugar de crear un trabajo complejo. ¿Qué hay de malo en arreglar el nombre en/temp/para que sea un nombre de módulo real? –

+1

Está fuera de mi control, las carpetas son creadas por el servidor de CI. – Art

Respuesta

19

primero se importe con importación:

>>> __import__('temp/a40bd22344') 
<module 'temp/a40bd22344' from 'temp/a40bd22344/__init__.py'> 

A continuación, asegúrese de que este módulo se conoce a Python como project:

>>> import sys 
>>> sys.modules['project'] = sys.modules.pop('temp/a40bd22344') 

Después de esto, nada importación proyecto en la sesión del pitón actual obtendrá el módulo original

>>> import project 
>>> project 
<module 'temp/a40bd22344' from 'temp/a40bd22344/__init__.py'> 

Esto funcionará también para los submódulos: si tiene un foobar.py en la misma ubicación, obtendrá

>>> import project.foobar 
>>> project.foobar 
<module 'project.foobar' from 'temp/a40bd22344/foobar.py'> 

Addendum. Esto es lo que estoy ejecutando:

>>> print sys.version 
2.5.2 (r252:60911, Jul 31 2008, 17:28:52) 
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] 
+0

Excelente, eso es lo que necesito, ¡gracias! – Art

+1

Excelente, excepto por el pequeño detalle de que no funciona: en Python 2.6 y 3.1 dice "ImportError: Importar por nombre de archivo no es compatible.", En 2.5 solo "ImportError: Ningún módulo llamado temp/a40bd22344", en __import__ (¡Acabo de probar los tres en mi Mac para confirmar que no había olvidado cómo funciona __import__!). Supongo que funciona en su plataforma, krawyoti, y la suya, Art, o no la habría marcado como aceptada, entonces tengo curiosidad: ¿qué plataformas son esas? –

+0

Bueno, es lógico pensar que esta laguna en __import__ que estaba usando estaba arreglada. Perezoso de mi parte no intentarlo en Python 2.6 también. – krawyoti

17

Sure, project = __import__('a40bd22344') después de que sys.path se configure correctamente, simplemente funcionará.

Suponga que desea hacerlo de una función de tomar la ruta completa como un argumento y el establecimiento de la importación mundial de project correctamente (así como hacer mágicamente import project trabajo después en otros módulos). Pedazo de pastel:

def weirdimport(fullpath): 
    global project 

    import os 
    import sys 
    sys.path.append(os.path.dirname(fullpath)) 
    try: 
     project = __import__(os.path.basename(fullpath)) 
     sys.modules['project'] = project 
    finally: 
     del sys.path[-1] 

esto también deja sys.path como lo encontró.

+0

Acabo de agregar una aclaración a mi pregunta, ¿funcionará también en este caso? – Art

+1

Alex, coloca la instrucción __import__ en un bracket try..finally, para asegurar que sys.path siempre se restaure correctamente. – krawyoti

+1

@Art, como @krawyoti dice que eso se logra pegándolo en sys.modules [project] como dice @krawyoti. @krawyoti, buen consejo: déjame editar para reflejar estos dos cambios. –

24

Aquí hay una manera de hacerlo, sin tocarse sys.path, utilizando el módulo imp en Python:

import imp 

f, filename, desc = imp.find_module('a40bd22344', ['/home/user/temp/']) 
project = imp.load_module('a40bd22344', f, filename, desc) 

project.some_func() 

Aquí hay un enlace a una buena documentación sobre el módulo de imp:

+1

Esto no toca sys.path, pero creo que usar imp hace que el paquete se vuelva a cargar cada vez que se ejecuta este código. Preferiría la solución de Alex porque hace lo correcto incluso si se ejecuta varias veces. –

Cuestiones relacionadas