2009-07-08 23 views
13

Angenommen, es gibt einen Ordner '/ home/user/temp/a40bd22344'. Der Name ist völlig zufällig und ändert sich in jeder Iteration. Ich muss in der Lage sein, diesen Ordner in Python mit einem festen Namen zu importieren, sagen wir "Projekt". Ich weiß, dass ich diesen Ordner zu sys.path hinzufügen kann, um Import-Lookup zu aktivieren, aber gibt es eine Möglichkeit, 'a40bd22344' durch 'Projekt' zu ersetzen?Namespace in Python überschreiben

Vielleicht einige clevere Hacks in init .py?

Hinzugefügt:

Es muss global sein - das heißt, andere Scripts 'Projekt' über die Standard-Laden:

import project 

haben ordnungsgemäß funktioniert, laden stattdessen a40bd22344.

+1

Warum können Sie nicht den Prozess zu beheben, die die temporäre Datei erstellt? Es wäre einfacher, dies an der Quelle zu beheben, anstatt einen aufwendigen Workaround zu erstellen. Was ist falsch daran, den Namen in/temp/zu korrigieren, um ein echter Modulname zu sein? –

+1

Es liegt außerhalb meiner Kontrolle, Ordner werden vom CI-Server erstellt. – Art

Antwort

19

Sie Erstimport es mit Import:

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

Dann stellen Sie sicher, dass dieser Modul Python als project bekannt wird:

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

Nach diesem etwas Projekt in der aktuellen Python-Session importieren wird die Original-Modul erhalten

Dies funktioniert auch für Untermodule: Wenn Sie ein foobar.py am gleichen Ort haben, erhalten Sie

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

Nachtrag. Hier ist, was ich laufen:

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

Ausgezeichnet, das ist was ich brauche, danke! – Art

+1

Ausgezeichnet, bis auf das kleine Detail, dass es nicht funktioniert: in Python 2.6 und 3.1 heißt es "ImportError: Import nach Dateiname wird nicht unterstützt.", In 2.5 nur "ImportError: Kein Modul namens temp/a40bd22344", auf dem __import__ (habe gerade alle drei auf meinem Mac versucht zu bestätigen, dass ich nicht vergessen habe, wie __import__ funktioniert! -). Ich nehme an, es funktioniert auf deiner Plattform, Krawyoti und deiner, Art, oder du hättest es nicht als akzeptiert markiert, also bin ich neugierig: welche Plattformen sind das? –

+0

Nun, es ist naheliegend, dass diese Lücke in __import__, die ich benutzte, behoben wurde. Faul von mir, es auch nicht in Python 2.6 zu versuchen. – krawyoti

17

Sicher, project = __import__('a40bd22344') nach sys.path ist richtig eingestellt wird nur funktionieren.

Angenommen, Sie es in einer Funktion unter den vollständigen Pfad als Argument und die Einstellung der globalen Import von project richtig (wie auch magisch machen import project Arbeit danach in anderen Modulen) tun wollen. Stück Kuchen:

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] 

dies verlässt auch sys.path, wie es gefunden wurde.

+0

Ich habe gerade meine Frage geklärt, wird es auch in diesem Fall funktionieren? – Art

+1

Alex, setzen Sie die Anweisung __import__ in eine try..finally-Klammer, um sicherzustellen, dass sys.path immer korrekt wiederhergestellt wird. – krawyoti

+1

@Art, wie @krawyoti sagt, dass dies erreicht wurde, indem man es in sys.modules [project] steckt, wie @krawyoti sagt. @ Krawyoti, guter Rat - lassen Sie mich bearbeiten, um diese beiden Änderungen widerzuspiegeln. –

24

Hier ist eine Möglichkeit, es zu tun, ohne sich zu berühren sys.path, das imp Modul in Python:

import imp 

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

project.some_func() 

Hier ist ein Link zu ein paar gute Dokumentation über die imp Modul:

+1

Dies berührt nicht sys.path, aber ich denke, dass die Verwendung von imp bewirkt, dass das Paket jedes Mal neu geladen wird, wenn dieser Code ausgeführt wird. Ich würde Alex Lösung vorziehen, weil es das Richtige tut, auch wenn es mehrmals ausgeführt wird. –

Verwandte Themen