2016-07-11 8 views
0

Ich bin mitten in der Veröffentlichung eines Python-Pakets, und bin über jeden Aspekt der Verpackung verwirrt.Brauchen Sie die richtige Verzeichnisstruktur für Python-Pakete und Richtlinien für gute API-Design

zu starten, ist meine Verzeichnisstruktur wie folgt:

SamplePackage/ 
- setup.py 
- README.rst 
- LICENSE.rst 
- sampledir/ 
    -__init__.py 
    -sample.py 
    -utils.py 

derzeit __init__ und setup unpopulated sind. sample.py ist die Datei, die jeder Benutzer des Pakets importieren möchte. Es enthält die API in Form von verschiedenen Funktionen: foo1, foo2.

utils.py enthält Helfer Fictions für smaple.py. Letztere enthält eine Aussage import utils

Noch unter dem sampledir Verzeichnis platziert Skripte können leicht import sample und die Fiktionen als sample.foo1() verwenden. Tritt ich aus diesem Verzeichnis heraus, kann ich import sampledir aufrufen, aber nicht import sample, was erwartet wird. Also muss ich from sampledir import sample tun. Dies führt zu einem Fehler auf der import utils Linie in sample.py

ImportError: No module named 'utils' 

Mancherorts ich import .utils für Dateien im selben Verzeichnis gesehen habe. Aber wenn ich das versuche, führt dies zu einem Syntaxfehler.

Warum kann ich sample.py nicht von außerhalb Samples importieren?

Auch welche Struktur Verzeichnis würde die Benutzer, die das Paket einfach installiert haben, um import sample von sample.foo1() gefolgt nennen, und müssen nicht from sampledir import sample oder import sampeldir.sample zu tun. Wenn Sie zum Beispiel die HTTP-Bibliothek requests verwenden, müssen Sie sie einfach importieren und requests.get(url) anrufen. requests.requests.get('url') ist nicht erforderlich, wie es in urllib ist. Was ist die korrekte Verzeichnisbenennung und -anordnung, um das zu erreichen, wenn ich möchte, dass das Paket sample heißt?

+0

Wenn Sie wollen, dass es wie 'requests' aussieht, [go and give' requests'] (https://github.com/kennethreitz/requests)! – jonrsharpe

Antwort

0

Zunächst einmal, ich habe Sie falsch verstanden, was der Unterschied zwischen Paket und Projekt ist. Sie Verzeichnisstruktur sollte __init__.py so etwas wie dieses

arbitrary_name_of_project/ 
- setup.py 
- README.rst 
- LICENSE.rst 
- package_name/ 
    -__init__.py 
    -sample.py 
    -utils.py 

Python-Paket ist „markiert“ durch ein Vorhandensein einer Datei sein. Python sucht auf seinem PYTHONPATH und sucht für alle Verzeichnisse mit der Datei __init__.py (einfach gesagt, es ist eigentlich viel komplizierter). Dies sind Pakete, die Sie während der Laufzeit importieren können.

In unserem Fall wird nur package_name Verzeichnis irgendwo zu PYTHONPATH installiert werden.Daher einmal (setup.py und disutils oder setuptools via) installiert haben, können Sie

import package_name 

nun eingeben, können Sie beliebige Klasse aufrufen oder Funktion oder was auch immer von jedem Modul in diesem Paket wie

package_name.sample.func1() 

Wenn Sie vermeiden wollen package_name.sample eingeben Sie anrufen, können Sie diese Zeile in __init__.py

platzieren
from .sample import func1 

Die Funktion func1 wird dann während der "Importzeit" in Ihren globalen Namensraum gestellt. Dies geschieht, wenn import package_name in Ihrem Programm ausgeführt wird. Dieses Rätsel kann dadurch gelöst werden, dass die Datei __init__.py jedes Mal ausgeführt wird, wenn das Paket importiert wird.

Es ist manchmal notwendig, die Struktur noch mehr zu spucken. Sie können Pakete "verschachtelt" haben (d. H. Pakete im Paket, die Sie importieren müssen). Es gibt auch Namespace-Pakete, in denen Sie ein Paket unter mehreren Verzeichnissen "spucken" können. Die Welt ist vielfältig. :)

Haftungsausschluss

schrieb ich, dass Sie den Code ohne Prüfung I zur Verfügung gestellt. Es könnte kleine Tippfehler geben, aber ich hoffe, dass die Geschichte mehr oder weniger korrekt ist. Bitte korrigiere mich wenn ich falsch liege.

Verwandte Themen