2008-11-13 8 views
6

Ich habe eine beträchtliche Anzahl von Python-Skripten, die wiederverwendbaren Code enthalten, die von anderen Python-Skripten verwendet und referenziert werden. Allerdings neigen diese Skripte dazu, über verschiedene Verzeichnisse verstreut zu sein, und ich finde es etwas mühsam, in meine Skripte auf oberster Ebene (meistens mehrere) Aufrufe von sys.path.append einzubeziehen. Ich möchte nur die "Import" -Anweisungen ohne die zusätzlichen Dateiverweise im selben Skript bereitstellen.Wie kann ich in Python Verweise zwischen Skriptdateien effizient verwalten?

Derzeit habe ich dies:

import sys 
sys.path.append('..//shared1//reusable_foo') 
import Foo 
sys.path.append('..//shared2//reusable_bar') 
import Bar 

Meine Präferenz wäre folgendes:

import Foo 
import Bar 

Mein Hintergrund ist in erster Linie in der .NET-Plattform, damit ich Meta-Dateien, die wie gewohnt bin * .csproj, * .vbproj, * .sln usw., um die tatsächlichen Dateipfadreferenzen außerhalb der Quelldateien zu verwalten und zu enthalten. Dies erlaubt mir, 'using'-Direktiven bereitzustellen (äquivalent zu Pythons Import), ohne alle Verweise freizugeben und die Pfadreferenzen selbst über mehrere Skripte hinweg wiederzuverwenden.

Hat Python dafür gleichwertige Unterstützung und wenn nicht, welche Techniken und Ansätze gibt es?

Antwort

3

Wenn Ihre wieder verwendbaren Dateien verpackt sind (das heißt, sie gehören __init__.py Datei) und der Pfad zu diesem Paket ist Teil Ihrer PYTHONPATH oder sys.path dann sollten Sie in der Lage sein, nur

import Foo 

zu tun This question bietet ein paar weitere Details.

(Anmerkung: Als Jim sagte, können Sie auch Ihre wiederverwendbaren Code in Ihr site-packages Verzeichnis löschen.)

1

Sie das wiederverwendbare Material in site-packages setzen kann. Das ist völlig transparent, da es standardmäßig in sys.path ist.

Sie können someName.pth Dateien in site-packages einfügen. Diese Dateien haben das Verzeichnis, in dem Ihr tatsächlich wiederverwendbares Zeug lebt. Dies ist auch völlig transparent. Und beinhaltet nicht den zusätzlichen Schritt der Installation einer Änderung in site-packages.

Sie können das Verzeichnis der wiederverwendbaren Sachen auf PYTHONPATH setzen. Das ist ein wenig weniger transparent, weil Sie sicherstellen müssen, dass es eingestellt ist. Nicht Raketenwissenschaft, aber nicht völlig transparent.

1

In einem Projekt wollte ich sicherstellen, dass der Benutzer Python-Skripte (die grundsätzlich als Plugins verwendet werden können) überall platzieren kann. Meine Lösung war für dieses Projekt der folgend in der Konfigurationsdatei zu setzen:

[server] 
PYPATH_APPEND: /home/jason:/usr/share/some_directory 

Auf diese Weise würde dies hinzufügen/home/jason und/usr/share/some_directory auf den Python-Pfad bei Programmstart.

Dann ist es nur eine einfache Angelegenheit der Teilung der Zeichenfolge durch die Doppelpunkte und das Hinzufügen dieser Verzeichnisse am Ende des sys.path. Vielleicht solltest du ein Modul in das site-packages-Verzeichnis einfügen, das eine Funktion enthält, um diese Konfigurationsdatei einzulesen und diese Verzeichnisse dem sys.path hinzuzufügen (leider habe ich momentan keine Zeit, um ein Beispiel zu schreiben) .

Wie andere erwähnt haben, ist es eine gute Idee, so viel wie möglich in Site-Pakete zu setzen und auch .pth-Dateien zu verwenden. Aber das kann eine gute Idee sein, wenn Sie ein Skript haben, das eine Menge Dinge importieren muss, die nicht in Site-Paketen enthalten sind, die Sie nicht aus anderen Skripten importieren möchten.

(es kann auch ein Weg sein, diese Dateien mit .pth zu tun, aber Ich mag in der Lage, die Python-Pfad an der gleichen Stelle zu manipulieren, wie ich den Rest meiner Konfiguration info put)

1

Der einfachste Weg, ist, PYTHONPATH zu setzen (oder hinzuzufügen) und Ihre Module und Pakete in einen in PYTHONPATH enthaltenen Pfad zu setzen (oder Symlink).

0

Meine Lösung ein Dienstprogramm zu verpacken war, dass das Modul importieren würde: my_util ist in site Pakete

import my_util 

foo = myutil.import_script('..//shared1//reusable_foo') 
if foo == None: 
    sys.exit(1) 


def import_script(script_path, log_status = True): 
    """ 
    imports a module and returns the handle 
    """ 
    lpath = os.path.split(script_path) 

    if lpath[1] == '': 
     log('Error in script "%s" in import_script' % (script_path)) 
     return None 


    #check if path is already in sys.path so we don't repeat 
    npath = None 
    if lpath[0] == '': 
     npath = '.' 
    else: 
     if lpath[0] not in sys.path: 
      npath = lpath[0] 

    if npath != None: 
     try: 
      sys.path.append(npath) 
     except: 
      if log_status == True: 
       log('Error adding path "%s" in import_script' % npath) 
      return None 

    try: 
     mod = __import__(lpath[1]) 
    except: 
     error_trace,error_reason = FormatExceptionInfo() 
     if log_status == True: 
      log('Error importing "%s" module in import_script: %s' % (script_path, error_trace + error_reason)) 
     sys.path.remove(npath) 
     return None 

    return mod 
Verwandte Themen