Si ritiene che Pythonic abbia più classi definite nello stesso file?


31

Lavorando con Python per la prima volta, ho scoperto che finisco per scrivere più classi nello stesso file, al contrario di altre lingue come Java, che utilizza un file per classe.

Di solito, queste classi sono composte da 1 classe di base astratta, con 1-2 implementazioni concrete il cui uso varia leggermente. Ho pubblicato uno di questi file qui sotto:

class Logger(object):

    def __init__(self, path, fileName):
        self.logFile = open(path + '/' + filename, 'w+')
        self.logFile.seek(0, 2)

    def log(self, stringtoLog):
        self.logFile.write(stringToLog)

    def __del__(self):
        self.logFile.close()

class TestLogger(Logger):   

    def __init__(self, serialNumber):
        Logger.__init__('/tests/ModuleName', serialNumber):

    def readStatusLine(self):
        self.logFile.seek(0,0)
        statusLine = self.logFile.readLine()
        self.logFile.seek(0,2)
        return StatusLine

    def modifyStatusLine(self, newStatusLine):
        self.logFile.seek(0,0)
        self.logFile.write(newStatusLine)
        self.logFile.seek(0,2)

class GenericLogger(Logger):

    def __init__(self, fileName):
        Logger.__init__('/tests/GPIO', fileName):

    def logGPIOError(self, errorCode):
        self.logFile.write(str(errorCode))

Come visto sopra, ho una classe base Logger, con un paio di differenze di implementazione al di sotto.

La domanda: questo standard è per Python o per qualsiasi lingua? Quali problemi potrebbero derivare dall'utilizzo di questa implementazione, se presente?

EDIT: Non sto davvero cercando una guida su questo file specifico , ma in senso più generale. E se le classi finissero con 3-5 metodi moderatamente complessi? Avrebbe senso dividerli allora? Dov'è il limite per dire che dovresti dividere un file?


3
Limitare a una classe per file NON è una cosa C ++. Java è l'unico linguaggio che conosco in cui è considerato qualcosa da evitare. In C ++, è estremamente comune che un singolo file .h / .cpp abbia una classe primaria e molte classi helper, che possono essere private o meno alla classe primaria.
Gort il robot il

@StevenBurnap Ho rimosso c ++ come esempio, poiché hai ragione.
Appunto

1
È anche fatto in php per facilitare il caricamento automatico. D'altra parte in php puoi dichiarare esplicitamente lo spazio dei nomi.
bodo,

Risposte:


24

Va bene. Va bene anche in C ++, per riferimento.

Tenere insieme cose strettamente legate è una pratica sensata. Evitare accoppiamenti inappropriati è anche una buona pratica. Trovare il giusto equilibrio non è una questione di regole rigide, ma di trovare un equilibrio tra preoccupazioni diverse.

Alcune regole pratiche:

  1. Dimensione

    I file eccessivamente grandi possono essere brutti, ma non è così nel caso qui. La bruttezza è probabilmente una buona ragione per dividere un file, ma sviluppare quel senso estetico è in gran parte una questione di esperienza, quindi non ti aiuta a capire cosa fare a priori

  2. Separazione degli interessi

    Se le tue implementazioni concrete hanno preoccupazioni interne molto diverse, il tuo singolo file accumula tutte quelle preoccupazioni. Ad esempio, le implementazioni con dipendenze non sovrapposte rendono il tuo singolo file dipendente dall'unione di tutte queste dipendenze.

    Pertanto, a volte potrebbe essere ragionevole considerare che l'accoppiamento delle sottoclassi alle loro dipendenze superi il loro accoppiamento all'interfaccia (o viceversa, la preoccupazione di implementare un'interfaccia è più debole delle preoccupazioni interne a tale implementazione).

    Come esempio specifico, prendere un'interfaccia di database generica. Le implementazioni concrete che utilizzano rispettivamente un DB in memoria, un RDBMS SQL e una query Web potrebbero non avere nulla in comune a parte l'interfaccia, e forzare chiunque desideri che la versione leggera in memoria importi anche una libreria SQL è sgradevole.

  3. incapsulamento

    Sebbene sia possibile scrivere classi ben incapsulate nello stesso modulo, ciò potrebbe incoraggiare un accoppiamento non necessario solo perché si ha accesso a dettagli di implementazione che altrimenti non verrebbero esportati al di fuori del modulo.

    Questo è solo uno stile povero, penso, ma potresti imporre una migliore disciplina suddividendo il modulo se davvero non riesci a rompere l'abitudine.


2
La tua risposta sarebbe più forte se citasse riferimenti esterni che dimostrano la normalità della combinazione di classi in un file o fornendo ulteriori spiegazioni indicando perché è OK.

1
Ho modificato la domanda per sottolineare che questo è semplicemente un esempio di ciò che intendo e non rappresenta esattamente la natura della domanda. Perché tenerli nello stesso file è meglio che semplicemente importarli dove necessario?
Appunto

Avere un sacco di piccoli file può essere difficile da gestire come avere alcuni file giganti. Python è un linguaggio abbastanza conciso. Il tuo esempio mostra questo. Queste tre classi sono direttamente correlate e probabilmente si adattano a una singola finestra dell'editor senza scorrere.
Gort il robot il

1
@ GlenH7 - Non sono sicuro dei riferimenti, dal momento che si spostano direttamente da me facendo una richiesta direttamente a me sostenendo che il mio bias di selezione è valido. Ho cercato invece di concentrarmi sulla spiegazione.
Inutile

7

I miei soliti documenti di riferimento per sapere cos'è Pythonic.

Semplice è meglio di complesso.

Flat è meglio di nidificato.

Dallo Zen di Python

Quasi senza eccezioni, i nomi delle classi usano la convenzione CapWords.

Nomi dei pacchetti e dei moduli I moduli dovrebbero avere nomi brevi, tutti in minuscolo. [...] I nomi dei moduli sono associati ai nomi dei file

Dal PEP 8

La mia interpretazione è che va bene in quanto manterrebbe le cose semplici e piatte. Inoltre, poiché i nomi delle classi e dei file hanno casi diversi, non dovrebbero essere identici comunque, quindi non vedrei alcun problema nell'imballare più classi correlate in un file.


7
Potresti ridurlo fino alle parti pertinenti alla domanda? Ho letto entrambi questi tempi multipli, ma faccio fatica a capire quali parti si riferiscono in particolare alla mia domanda attuale.
Appunto

1
In effetti, ho modificato la mia risposta.
SylvainD,

1

Quello che hai ora va bene. Vai e sfoglia la libreria standard: ci sono molti moduli con più classi correlate in un singolo file. Ad un certo punto, le cose si ingrandiscono e alla fine vorrai iniziare a utilizzare moduli con più file, ma non ci sono regole reali su quando. Le cose si dividono quando un file inizia a sembrare "troppo grande".


0

Va decisamente bene e ti incoraggio a tenere diverse classi in un unico file purché siano realizzate. In generale le tue classi dovrebbero rimanere brevi e concise e dovresti piuttosto dividere il comportamento in due o più classi piuttosto che costruirne enormi monolitiche. Quando si scrivono diverse classi di piccole dimensioni, è davvero necessario e utile conservare quelle correlate nello stesso file.


-1

In breve - inferno sì.

Inoltre, avere più classi in un singolo file è talvolta molto utile. Alcuni pacchetti ( six, bottle) vengono spediti esplicitamente in un singolo file per essere facilmente integrati in qualsiasi modulo di terze parti senza essere installati (a volte desiderabili). Ma assicurati di organizzare bene il tuo codice. Usa intensamente i commenti sul codice e i blocchi di separazione per renderlo più leggibile.


3
questo non sembra aggiungere nulla di sostanziale rispetto alla precedente risposta pubblicata qualche anno fa
moscerino
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.