Qual è un buon modo per ordinare i metodi in una classe Python?


89

Voglio ordinare i metodi in una classe Python ma non so qual è l'ordine corretto.

Quando estraggo metodi in Eclipse con PyDev, Eclipse inserisce il metodo estratto sopra il metodo modificato. Ma questo mette i dettagli di livello inferiore prima dei dettagli di livello superiore. Secondo lo zio Bob dovrei fare l'opposto in modo che il mio codice si legga come i titoli di un giornale. Quando programma Java seguo semplicemente i suoi consigli.

Qual è la migliore pratica per Python?


8
Non esiste una best practice. Fai ciò che ha più senso: le cose importanti in alto sono una buona idea e la coerenza è generalmente una buona cosa. PEP-8 non lo menziona e se fosse scolpito nella pietra, sarebbe lì che sarebbe.
Gareth Latty

4
E anche PEP8 non è sempre scolpito nella pietra.
Ignacio Vazquez-Abrams

1
Di solito lo faccio per gruppo sulla funzionalità (get, set, ecc.)
CppLearner

È importante notare che l'ordine delle funzioni del metodo può essere arbitrario, perché una dichiarazione di classe definisce solo le sue funzioni del metodo, non le richiama . Ciò consente al codice sorgente delle routine del metodo di classe di utilizzare con successo le funzioni del metodo che verranno definite in seguito nell'elenco.
DragonLord

Risposte:


67

Come altri hanno sottolineato, non esiste un modo giusto per ordinare i tuoi metodi. Forse un suggerimento PEP sarebbe utile, ma comunque. Vorrei provare ad affrontare la tua domanda nel modo più obiettivo possibile.

  • Prima le interfacce: i metodi pubblici e le funzioni magiche di Python definiscono l'interfaccia della classe. La maggior parte delle volte, tu e altri sviluppatori desiderate utilizzare una classe anziché modificarla. Quindi saranno interessati all'interfaccia di quella classe. Metterlo al primo posto nel codice sorgente evita di scorrere i dettagli di implementazione che non ti interessano.

  • Proprietà, metodi magici , metodi pubblici: è difficile definire l'ordine migliore tra questi tre, che fanno tutti parte dell'interfaccia della classe. Come dice @EthanFurman, è molto importante attenersi a un sistema per l'intero progetto. In generale, le persone si aspettano __init__()la migliore prima funzione della classe, quindi proseguo con gli altri metodi magici proprio sotto.

  • Ordine di lettura: fondamentalmente, ci sono due modi per raccontare una storia: dal basso verso l'alto o dall'alto verso il basso. Mettendo al primo posto le funzioni di alto livello, uno sviluppatore può ottenere una comprensione approssimativa della classe leggendo le prime due righe. Altrimenti, si dovrebbe leggere l'intera classe per avere una comprensione della classe e la maggior parte degli sviluppatori non ha il tempo per questo. Come regola pratica, metti i metodi sopra tutti i metodi chiamati dal loro corpo.

  • Metodi di classe e metodi statici: di solito, questo è implicito nell'ordine di lettura spiegato sopra. I metodi normali possono chiamare tutti i metodi volte e quindi vengono prima. I metodi di classe possono chiamare solo metodi di classe e metodi statici e vengono dopo. I metodi statici non possono chiamare altri metodi della classe e sono ultimi.

Spero che sia di aiuto. La maggior parte di queste regole non sono specifiche di Python, comunque. Non sono a conoscenza di un linguaggio che imponga l'ordine dei metodi, ma in tal caso sarebbe piuttosto interessante e per favore commenta.


1
Di solito una lingua non impone l'ordinamento. Ma alcune lingue hanno convenzioni comuni. Ad esempio, C # StyleCop ha regole di ordinamento rigide. Per Java vedere stackoverflow.com/questions/4668218 , ecc
xmedeko

1
metodi di classe: questi sono spesso usati come costruttori e quindi in genere chiamano __init__esplicitamente (in combinazione con __new__) o implicitamente (tramite il costruttore predefinito), quindi sarebbe una ragione per metterli insieme __init__. (Anche se non li ho mai visti posizionati prima __init__ .)
oulenz

15

Non esiste un ordine corretto. Scegli un sistema e seguilo. Quello che uso è:

class SomeClass(object):
    def __magic_methods__(self):
        "magic methods first, usually in alphabetical order"
    def _private_method(self):
        "worker methods next, also in alpha order"
    def a_method(self):
        "then normal methods, also in alpha order"

2
Qual è la tua preferenza per metodi statici, variabili di classe e metodi decorati @property?
John Mee,

@ JohnMee: variabili di classe che ho messo prima di ogni altra cosa; miei metodo di piegatura nasconde il @staticmethod, @classmethod, @property, e le altre @decoratorlinee in modo da utilizzare il tipo di metodo per determinare dove va (con l'eccezione che le proprietà tendono ad andare tra _private_methodse normal_methods).
Ethan Furman

Quindi, se l'ordine fondamentalmente passa da metodi "magici" molto privati ​​a metodi privati ​​e normali, significa che @classmethods come next ( @classmethod def a_class_method(cls)) @staticmethode poi s ( @staticmethod def a_static_method())? Almeno questa è la politica per come la intendo io ... (senza che il mio IDE ripieghi nulla perché non mi piace)
Kawu

2

Faccio qualcosa di simile a @Ethan che ho visto nel sorgente di Django, dove la differenza principale è il grande "############" blocco dei commenti per delimitare le aree. Per esempio,

class SomeClass(object):
    #################
    # Magic Methods #
    #################
    def __magic_methods__(self):
        "magic methods first"

    ##################
    # Public Methods #
    ##################
    def a_method(self):
        "then normal methods, in order of importance"

    ###################
    # Private Methods #
    ###################
    def _private_method(self):
        "then worker methods, grouped by importance or related function"

Ovviamente questo è meno utile per le classi più piccole.


19
Ma posso vedere che sono magici, pubblici o privati. Personalmente non mi piacciono questi blocchi di commenti; Posso guardare il codice piegato se voglio vedere un elenco di tutti loro. Avere un commento sopra un particolare blocco di metodi relativi alla funzionalità è qualcosa che farei, ma per questo tipo di commento è quello che mi dicono i nomi dei metodi.
Chris Morgan

Di nuovo, lo faccio solo per classi più grandi. Trovo sia facile confondere i metodi magici con i metodi semi-privati ​​( ) e alterati dal nome (_ ).
Matt Luongo

Stavo rimuovendo i brutti ####blocchi a metà modifica quando ho capito che li avresti messi lì apposta! Sono d'accordo con l' ordine , tuttavia, che è l'argomento di questa domanda. Consiglierei di rimuovere il ####da questo esempio poiché non riguarda l'ambito della domanda e il tuo esempio è di una piccola classe, per la quale non ####useresti comunque. :-)
Mateen Ulhaq

1
@MateenUlhaq si prega di fare riferimento alla seconda e alla quinta linea guida visualizzate nella schermata di modifica: "chiarire il significato senza modificarlo" e " rispettare sempre l'autore originale". (Nota che questi sono pensati per essere applicati incondizionatamente, senza rispetto per l'opinione dell'editore.) L'intero e unico punto di questa risposta era di visualizzare quei brutti blocchi di commenti; senza di loro, dice esattamente la stessa cosa della risposta di Ethan e non ha senso che sia qui. Hai anche riconosciuto che i blocchi erano lì " apposta " - sapendo questo, perché dovresti andare a rimuoverli?
ciao

1
@MIWright Ho pensato che fosse al di fuori dell'ambito della domanda. Come puoi vedere, rev2 contiene ancora materiale che risponde alla domanda in modo diverso da quello di Ethan, con un diverso ordine (e subordinazione!). Tuttavia, è tornato indietro.
Mateen Ulhaq
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.