2009-07-08 17 views
13

Załóżmy, że istnieje folder "/ home/user/temp/a40bd22344". Nazwa jest całkowicie losowa i zmienia się w każdej iteracji. Muszę mieć możliwość importowania tego folderu w Pythonie przy użyciu stałej nazwy, powiedzmy "projekt". Wiem, że mogę dodać ten folder do sys.path, aby włączyć wyszukiwanie importu, ale czy istnieje sposób na zastąpienie "a40bd22344" przez "projekt"?Zastępowanie przestrzeni nazw w Pythonie

Może jakieś sprytne hacki w init .py?

Dodano:

To musi być globalny - czyli inne skrypty loading 'przedsięwzięcie' poprzez normy:

import project 

Czy działał poprawnie, załadunek a40bd22344 zamiast.

+1

Dlaczego nie można naprawić procesu, który utworzył plik tymczasowy? Łatwiej byłoby to naprawić u źródła, zamiast tworzyć skomplikowaną pracę. Co jest złego w ustalaniu nazwy w/temp /, aby była prawdziwą nazwą modułu? –

+1

To poza moją kontrolą, foldery są tworzone przez serwer CI. – Art

Odpowiedz

19

Najpierw importujesz go pod import:

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

Następnie należy upewnić się, że moduł ten zostanie znany Pythonie jak project:

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

Po tym, coś importowanie projektu w bieżącej sesji Pythona otrzyma oryginalny moduł

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

Będzie to działać również dla podmodułów: jeśli masz foobar.py w tej samej lokalizacji, dostaniesz

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

Dodatek. Oto, co robię:

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

Doskonale, tego potrzebuję, dzięki! – Art

+1

Doskonały, z wyjątkiem drobnego szczegółu, który nie działa: w Pythonie 2.6 i 3.1 jest napisane "ImportError: Importowanie według nazw plików nie jest obsługiwane.", W 2.5 tylko "ImportError: Brak modułu o nazwie temp/a40bd22344", na __import__ (po prostu wypróbowałem wszystkie trzy na moim Macu, aby potwierdzić, że nie zapomniałem jak działa __import__!). Zakładam, że działa na waszej platformie, krawyoti i waszym, Art, albo nie oznaczilibyście tego jako zaakceptowanego, więc jestem ciekawy: jakie to są platformy? –

+0

Cóż, to oznacza, że ​​ta luka w __import__, której używałem została naprawiona. Leniwe, żebym nie wypróbował tego w Pythonie 2.6. – krawyoti

17

Pewnie, project = __import__('a40bd22344') po ustawieniu sys.path po prostu zadziała.

Załóżmy, że chcesz to zrobić w funkcji biorąc pełną ścieżkę jako argument i zachodzącego import projectglobalny prawidłowo (jak również magicznie dokonywania import project pracę później w innych modułach). Bułka z masłem:

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] 

pozostawia również sys.path, jak znalazł.

+0

Właśnie dodałem wyjaśnienie do mojego pytania, czy będzie ono działać również w tym przypadku? – Art

+1

Alex, umieść instrukcję __import__ w nawiasie try..finally, aby upewnić się, że sys.path jest zawsze poprawnie odtwarzana. – krawyoti

+1

@Art, jak @krawyoti mówi, że jest to osiągnięte przez przyklejenie go do sys.modules [projektu], jak mówi @krawyoti. @krawyoti, dobra rada - pozwól mi edytować, aby odzwierciedlić te dwie zmiany. –

24

Oto jeden ze sposobów, aby to zrobić, nie dotykając sys.path, za pomocą modułu imp w Pythonie:

import imp 

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

project.some_func() 

Oto link do jakiejś dobrej dokumentacji na module imp:

+1

To nie ma wpływu na sys.path, ale myślę, że użycie imp powoduje, że pakiet jest ładowany za każdym razem, gdy ten kod jest wykonywany. Wolałbym rozwiązanie Alexa, ponieważ robi to dobrze, nawet jeśli jest wykonywane wielokrotnie. –