2009-04-20 5 views
3

Angenommen, ich habe diese Barebone-Struktur:Wie strukturiere ich Python-Code in Module/Pakete?

project/ 
    main.py 
    providers/ 
    __init.py__ 
    acme1.py 
    acme2.py 
    acme3.py 
    acme4.py 
    acme5.py 
    acme6.py 

Angenommen, main.py enthält (teilweise):

if complexcondition(): 
    print providers.acme5.get() 

Wo __init__.py leer ist und acme*.py enthalten (teilweise):

def get(): 
    value=complexcalculation() 
    return value 

Wie ändere ich diese Dateien zu arbeiten?

Hinweis: Wenn die Antwort "import acme1", "import acme2" usw. in __init__.py lautet, gibt es eine Möglichkeit, dies zu erreichen, ohne sie alle von Hand aufzulisten?

+1

verwenden, wie Sie es schon sollte beschrieben arbeiten. .. welche Probleme hast du? –

+0

Duplizieren: http://stackoverflow.com/questions/106896/how-many-python-classes-should-i-put-in-one-file; http://stackoverflow.com/questions/171785/how-do-you-organize-python-modules; http://stackoverflow.com/questions/391879/organising-my-python-project –

Antwort

3

Diese Frage heute gestellt, Dynamic Loading of Python Modules, sollte Ihre Antwort haben.

+0

Nicht ganz was ich mir erhofft hatte, aber es hat mich zu einer praktikablen Lösung geführt, danke. – arantius

5

Wenn ich Ihre Frage richtig lese, sieht es so aus, als würden Sie keinen dynamischen Import durchführen (wie in der von Van Gale erwähnten Frage), sondern versuchen, nur alle Module in den Providern zu importieren Paket. Wenn das der Fall ist, in __init__.py würden Sie diese Aussage haben:

__all__ = ["acme1", "acme2", "acme3", "acme4", "acme5", "acme6"] 

Dann ist alles zu importieren, die Sie von ... import *

from providers import * 

Und dann statt mit dem Paketnamen verwenden würden, explizit im Code, würden Sie nur die importierten Klassen rufen

acme1.get() 
acme2.get() 

Wenn Sie genug Module im Provider-Paket haben, dass es ein Problem, diebevölkern wirdListe, möchten Sie vielleicht in kleinere Pakete oder die Speicherung der Daten auf andere Weise zu brechen. Ich persönlich würde nicht jedes Mal, wenn ich das Paket wiederverwenden möchte, mit dynamischen Import-Schennagins umgehen müssen.

6

hey! zwei Jahre später, aber ... vielleicht könnte hilfreich zu einem gewissen ein

machen Ihre Anbieter/__ init__.py wie folgt aus:

import os 
import glob 

module_path = os.path.dirname(__file__) 
files = glob.glob(os.path.join(module_path, 'acme*.py')) 
__all__ = [os.path.basename(f)[:-3] for f in files] 

Sie müssen es später nicht ändern, wenn hinzufügen oder entfernen jeder Anbieter/acme * Py

dann from providers import * in main.py

+0

Dies führt "Magie" ein; d. h. unerwartete Nebeneffekte. Das bloße Vorhandensein einer Datei sollte nicht zur Codeausführung führen. Dies widerspricht dem Prinzip der geringsten Überraschung und macht dies zu einer schlechten Idee (tm). -1 – Ondergetekende

+0

@koert was ist los mit ein bisschen Magie? : P In diesem Fall lautet die Frage: "Gibt es eine Möglichkeit dies zu erreichen, ohne sie alle mit der Hand aufzuzählen?" ... er bittet um ein wenig Magie, denke ich. Vielleicht werden die Dateien automatisch generiert und er möchte seinen Code nicht jedes Mal bearbeiten, wenn ein neuer erscheint. Wie kannst du das ohne Magie erreichen? – remosu

+0

Sie haben Recht, es gibt keine Möglichkeit, Ihre Szenarien ohne Magie zu erreichen. Auf der anderen Seite ist diese Art von Magie der Beginn einer Sysadmin-Hölle (dort gewesen, das getan). – Ondergetekende