2009-06-18 13 views
12

Wie referenziere ich eine Datei relativ zum Verzeichnis eines Pakets?Relative Dateipfade in Python-Paketen

Meine Verzeichnisstruktur ist:

 
    /foo 
    package1/ 
     resources/ 
     __init__.py 
    package2/ 
     resources/ 
     __init__.py 
    script.py 

script.py Importe Pakete package1 und package2. Obwohl die Pakete von jedem anderen Skript auf dem System importiert werden können. Wie sollte ich Ressourcen im Inneren referenzieren, sagen wir package1, um sicherzustellen, dass es funktioniert, falls os.path.curdir willkürlich ist?

Antwort

14

Wenn Sie Dateien aus dem Ordner foo/package1/resources referenzieren möchten, verwenden Sie die Variable __file__ des Moduls. Innerhalb foo/package1/__init__.py:

from os import path 
resources_dir = path.join(path.dirname(__file__), 'resources') 
+0

Wie in einer anderen Antwort erwähnt, funktioniert dies nicht, wenn Ihre Anwendung in einer Zip-Datei gepackt ist. – Glyph

0

Dies ist eine schlechte Idee, weil, wenn Ihr Paket als gezippte Ei installiert wurde, dann können Ressourcen nicht zur Verfügung stehen.

Wenn Sie setsetool verwenden, vergessen Sie nicht, zip_safe = False zur setup.py-Konfiguration hinzuzufügen.

+3

Das stimmt, aber eigentlich hätte es eher in einem Kommentar als in einer Antwort liegen sollen, da es die Frage nicht beantwortet. – Glyph

4

Sie können zip-sicher sein und gleichzeitig eine praktische API verwenden, wenn Sie twisted.python.modules verwenden.

Zum Beispiel, wenn ich eine data.txt mit etwas Text in ihm haben und und diese sample.py in einem Verzeichnis:

from twisted.python.modules import getModule 
moduleDirectory = getModule(__name__).filePath.parent() 
print repr(moduleDirectory.child("data.txt").open().read()) 

dann sample Import wird dies tun:

>>> import sample 
'Hello, data!\n' 
>>> 

Wenn Ihr Modul in einem normalen Verzeichnis wird getModule(__name__).filePath ein FilePath sein; Wenn es sich um eine Zip-Datei handelt, handelt es sich um eine ZipPath, die die meisten, aber nicht alle APIs unterstützt.

4

Ein einfacher/sicherer Weg, dies zu tun, um die resource_filename Methode von pkg_resources verwendet (die mit setuptools verteilt ist) wie folgt:

from pkg_resources import resource_filename 
filepath = resource_filename('package1', 'resources/thefile') 

Oder, wenn Sie diesem in package1/___init___.py sind Implementierung:

from pkg_resources import resource_filename 
filepath = resource_filename(__name__, 'resources/thefile') 

Dies gibt Ihnen eine saubere Lösung, die auch (wenn ich mich nicht irre) zip sicher ist.