2013-03-06 22 views
5

Ich mag würde Module/packages Struktur wie folgt haben:Python-Modulen Hierarchie Namenskonvention

/__init__.py 
/mymodule.py 
/mymodule/ 
/mymodule/__init__.py 
/mymodule/submodule.py 

Und dann verwenden Module wie:

import mymodule 
import mymodule.submodule 

Aber es scheint, als ob Datei "mymodule. py "Konflikte mit" mymodule "Verzeichnis.

Wie lautet die korrekte Namenskonvention hier?

Danke.

Antwort

11

Wenn Sie ein Paket erstellen möchten, müssen Sie verstehen, wie Python übersetzt Dateinamen zu Modulnamen.

Die Datei mymodule.py ist als mymodule verfügbar, vorausgesetzt, der Interpreter findet sie in einem Verzeichnis im Python-Suchpfad. Wenn Sie ein Dateisystem verwenden, bei dem die Groß-/Kleinschreibung nicht berücksichtigt wird, kann es möglicherweise auch mit einer anderen Groß-/Kleinschreibung importiert werden (Sie sollten jedoch ein solches systemabhängiges Verhalten vermeiden).

Ein Paket ist ein Verzeichnis mit einer __init__.py Datei darin. Es hat in letzter Zeit einige Bewegungen gegeben, Pakete ohne diese Dateien zuzulassen, aber ich werde diesen weniger häufigen Fall für diese Antwort ignorieren. Ein Paket wird zu einem Modul in Python, dessen Code aus der Datei __init__.py stammt. So kann die Datei mypackage/__init__.py als mypackage importiert werden.

Es gibt keine Bedeutung für eine __init__.py Datei direkt im Python-Suchpfad (naja, ich nehme an, Sie könnten es importieren ein __init__-Modul, aber das ist wahrscheinlich eine schlechte Idee).

Also, für Ihre Situation, hier ist das entsprechende Dateisystem-Layout:

toplevel/ 
    mymodule/ 
     __init__.py  # put code here for mymodule 
     submodule.py # put code here for mymodule.submodule 

Nur die toplevel Ordner in dem Python-Suchpfad sein sollten.

+0

Ich habe gesehen, dass Python-Leute davon abraten, signifikanten Code in 'mymodule/__ init __. Py' zu legen, obwohl z. [Alex Martelli] (http://stackoverflow.com/a/2361278/188535), die damit im Widerspruch zu stehen scheint. (Nicht dass ich das unbedingt stimme ...) – detly

+2

Das stimmt. Ein beliebterer Stil wäre es, den eigentlichen Code für "meinModul" in ein undokumentiertes Submodul zu schreiben und dann die öffentliche API dafür in "__init __. Py" zu importieren. – Blckknght

+0

danke für informative antwort. Es ist schade, dass Python solche schmutzigen Hacks benötigt, um eine offensichtliche Sache zu tun. –

4

Sie haben es mit einem package zu tun. Die Paketstruktur sollten Sie haben, ist:

/some-parent-directory # This needs to be on sys.path 
    /mymodule # This is not really a module - it's a package 
     __init__.py # import mymodule 
     # init is loaded when you `import mymodule` or anything below it 
     some.py # import mymodule.some 
     implementation.py # import mymodule.implementation 
     files.py # import mymodule.files 
     /submodule 
      __init__.py # import mymodule.submodule 
      # init is loaded when you `import mymodule.submodule` or anything below it 
      submodule_impl.py # import mymodule.submodule.submodule_impl 
      goes.py # import mymodule.submodule.goes 
      here.py # import mymodule.submodule.here 

Solange die Eltern Verzeichnis auf sys.path ist können Sie import mymodule oder from mymodule.submodule import something ohne Probleme nennen.

Wenn Sie etwas wollen, von der Root-Ebene eines Pakets zur Verfügung stehen (i. E. from mymodule import SomeItem oder aus einem Unterpaket from mymodule.submodule import AnotherItem), dann können Sie es in die entsprechende __init__.py-Datei importieren.

Nehmen wir also an, Sie möchten, dass die im Modul CustomClass definierte Klasse submodule_impl.py direkt aus submodule importiert werden kann. Ihre submodule/__init__.py würde folgendes enthalten:

from .submodule_impl import CustomClass 

Dann würden Sie in der Lage sein CustomClass direkt zu importieren aus submodule (dh from mymodule.submodule import CustomClass)