Sono abituato al modello Java in cui puoi avere una classe pubblica per file. Python non ha questa restrizione e mi chiedo quale sia la migliore pratica per organizzare le classi.
Sono abituato al modello Java in cui puoi avere una classe pubblica per file. Python non ha questa restrizione e mi chiedo quale sia la migliore pratica per organizzare le classi.
Risposte:
Un file Python è chiamato "modulo" ed è un modo per organizzare il software in modo che abbia "senso". Un'altra è una directory, chiamata "pacchetto".
Un modulo è una cosa distinta che può avere una o due dozzine di classi strettamente correlate. Il trucco è che un modulo è qualcosa che importi, e hai bisogno che l'importazione sia perfettamente sensibile alle persone che leggeranno, manterranno ed estenderanno il tuo software.
La regola è questa: un modulo è l'unità di riutilizzo .
Non puoi riutilizzare facilmente una singola classe. Dovresti essere in grado di riutilizzare un modulo senza alcuna difficoltà. Tutto nella tua libreria (e tutto ciò che scarichi e aggiungi) è un modulo o un pacchetto di moduli.
Ad esempio, stai lavorando su qualcosa che legge fogli di calcolo, esegue alcuni calcoli e carica i risultati in un database. Come vuoi che sia il tuo programma principale?
from ssReader import Reader
from theCalcs import ACalc, AnotherCalc
from theDB import Loader
def main( sourceFileName ):
rdr= Reader( sourceFileName )
c1= ACalc( options )
c2= AnotherCalc( options )
ldr= Loader( parameters )
for myObj in rdr.readAll():
c1.thisOp( myObj )
c2.thatOp( myObj )
ldr.laod( myObj )
Pensa all'importazione come al modo in cui organizzare il codice in concetti o blocchi. Il numero esatto di classi presenti in ciascuna importazione non ha importanza. Ciò che conta è l'organizzazione generale che stai rappresentando con le tue import
dichiarazioni.
Poiché non esiste un limite artificiale, dipende davvero da ciò che è comprensibile. Se hai un gruppo di classi abbastanza brevi e semplici che sono raggruppate logicamente insieme, aggiungine un po '. Se hai classi grandi e complesse o classi che non hanno senso come gruppo, scegli un file per classe. Oppure scegli una via di mezzo. Refactoring man mano che le cose cambiano.
Mi piace il modello Java per il seguente motivo. Posizionare ogni classe in un singolo file promuove il riutilizzo rendendo le classi più facili da vedere durante la navigazione nel codice sorgente. Se hai un gruppo di classi raggruppate in un singolo file, potrebbe non essere ovvio agli altri sviluppatori che ci sono classi che possono essere riutilizzate semplicemente sfogliando la struttura delle directory del progetto . Quindi, se pensi che la tua classe possa essere riutilizzata, la inserirò nel suo file.
Dipende interamente da quanto è grande il progetto, da quanto sono lunghe le classi, se verranno utilizzate da altri file e così via.
Ad esempio, uso abbastanza spesso una serie di classi per l'astrazione dei dati, quindi potrei avere 4 o 5 classi che possono essere lunghe solo 1 riga ( class SomeData: pass
).
Sarebbe stupido dividere ciascuno di questi in file separati, ma poiché possono essere usati da file diversi, mettere tutti questi in un data_model.py
file separato avrebbe senso, quindi posso farlofrom mypackage.data_model import SomeData, SomeSubData
Se hai una classe con molto codice, magari con solo alcune funzioni che usa, sarebbe una buona idea dividere questa classe e le funzioni di supporto in un file separato.
Dovresti strutturarli in modo da farlo from mypackage.database.schema import MyModel
, no from mypackage.email.errors import MyDatabaseModel
- se il luogo da cui stai importando le cose ha senso ei file non sono lunghi decine di migliaia di righe, l'hai organizzato correttamente.
La documentazione dei moduli Python contiene alcune informazioni utili sull'organizzazione dei pacchetti.
Mi ritrovo a dividere le cose quando sono infastidito dalla grandezza dei file e quando la struttura desiderabile della relazione inizia ad emergere naturalmente. Spesso queste due fasi sembrano coincidere.
Può essere molto fastidioso se dividi le cose troppo presto, perché inizi a capire che è necessario un ordinamento della struttura completamente diverso.
D'altra parte, quando qualsiasi file .java o .py arriva a più di 700 righe, comincio a infastidirmi costantemente cercando di ricordare dove si trova "quel particolare bit".
Con Python / Jython anche la dipendenza circolare delle istruzioni di importazione sembra avere un ruolo: se provi a dividere troppi blocchi di costruzione di base cooperanti in file separati questa "restrizione" / "imperfezione" del linguaggio sembra costringerti a raggruppare le cose, forse in modo piuttosto sensato.
Per quanto riguarda la suddivisione in pacchetti, non lo so davvero, ma direi che probabilmente la stessa regola del fastidio e dell'emergere di una struttura felice funziona a tutti i livelli di modularità.
Direi di mettere quante più classi possono essere raggruppate logicamente in quel file senza renderlo troppo grande e complesso.