2011-11-09 5 views
5

Sto provando a strutturare la mia app in Python. Tornando da C#/Java, mi piace l'approccio di una classe per file. Vorrei che il mio albero del progetto di simile a questa:Python una classe per modulo e pacchetti

[Service] 
    [Database] 
     DbClass1.py 
     DbClass2.py 
    [Model] 
     DbModel1.py 
     DbModel2.py 
    TheService.py 
[ServiceTests] 
    [Database] 
     DbClass1Tests.py 
     DbClass2Tests.py 
    [Model] 
     DbModel1Tests.py 
     DbModel2Tests.py 
    TheServiceTests.py 
  1. è quella classe per ogni approccio ok file in Python?
  2. E 'possibile creare pacchetti/moduli in modo tale che i pacchetti funzionano come i pacchetti di Java o spazi dei nomi del NET, cioè in DbModel1Tests.py:

    import Service.Model 
    
    def test(): 
        m = DbModel1() 
    
+9

È possibile, come (invece di raggruppandoli in directory come si farebbe con la 1 classe per file system.) dare un'occhiata a [PEP 8 - Style Guide for Python Code] (http://www.python.org/dev/peps/pep-0008/). –

risposta

4

A mio parere, per 1: non vedo perché no. Penso che, indipendentemente dal linguaggio, questa sia una buona idea in quanto fornisce una rapida panoramica di ciò che si trova in un file quando si sa che ci sarà solo una singola classe in esso. Tuttavia, farei una piccola eccezione per le classi helper, ma poichè Python consente classi annidate, questo può anche essere fatto abbastanza bene.

Per 2: anche possibile. Nel tuo esempio, però, è sufficiente caricare il modulo, rendendo così disponibili le sue classi e funzioni tramite lo spazio dei nomi completo.

Quindi, se si dice import Service.Model, è possibile accedere alla classe solo utilizzando m = Service.Model.DBModel1().

Per importare le cose nello spazio dei nomi corrente, fare un from Service.Model import * (o from Service.Model import DBModel1 se è necessario solo quella classe). Quindi puoi fare come fai attualmente: m = DBModel1().

+5

La fine sembra un po 'fuorviante - usando la struttura dell'OP, non sarebbe necessario scrivere 'm = DBModel1.DBModel1()' dopo 'da Service.Model import DBModel1' (assumendo che il nome della classe sia uguale a quello di .py file) ? – jwd

3

Si può avere una classe per modulo, ma questo non è richiesto. Direi che è più legato alla lunghezza di ogni modulo (tenerli non troppo a lungo è sempre una buona idea).

Ora, circa la vostra struttura:

  • è possibile dichiarare le sottocartelle come pacchetti. Per questo, basta creare un file __init__.py in ciascuna sottocartella.
  • una volta fatto questo, è possibile importare i moduli in questo modo: from Service.Model import DbModel e utilizzare questo come si scrive: m = DbModel1.DbModel1Class()

Note:

  • di denominazione dei file con prima lettera in maiuscolo non è davvero Pythonic (ma il nome della classe dovrebbe averlo). Ciò significa che dovrebbe apparire come service.model.dbModel1.DbModel1().
  • è possibile eseguire from Service.Model import DbModel1 per importare direttamente la classe dal modulo DbModel1. Questo può essere fatto attraverso l'impostazione corretta del contenuto di __init__.py (non so come configurarlo esattamente). Some more informations here.
13

Q1. È possibile utilizzare lo stile 1 classe per file in Python, ma ciò è insolito.

Q2. dovresti usare from Service.Model import * e fare alcune cose in Service/Model/__init__.py che in genere è disapprovato.Evitare import * in Python

Il mio consiglio personale su questo: Python è non C#/Java. Cercare di piegarlo per far sembrare $ other_language causerà frustrazione e scarsa esperienza utente.

Tenete a mente che:

  • si può avere altra roba di classi in moduli Python (funzioni, per esempio)
  • non si dispone di importare una classe da un modulo a meno che non è necessario istanziare quella classe. In particolare, se il codice utilizza solo istanze di DbModel1 che vengono passate come argomenti alle funzioni/metodi, non è necessario importare in quella parte del codice
  • da Service.Model.DbModel1 import DbModel1. Preferisce from service.model import DbModel1: evitare le lettere maiuscole nei nomi di file e directory, e lezioni di gruppo/funzioni logicamente in file
+0

Perché avere una classe per i file insoliti in Python? – Gewthen

+0

@Giremo che non è obbligatorio dalla lingua, quindi non è una pratica comune. –

+1

Indipendentemente dal fatto che sia d'accordo o meno, questa risposta potrebbe essere resa più utile se alcuni dei "do e non do" hanno qualche spiegazione e ragionamento dietro di essi. La menzione di pep 8 potrebbe aiutare su alcuni dei tuoi punti, ma altri hanno bisogno di più (ad esempio "generalmente accigliato", "sembra cattivo"). – Gewthen