Generalmente le classi in Python influenzano la leggibilità / le prestazioni?

1

Ho un set di classi che rappresentano oggetti diversi (tabelle in un database):

class ObjA:
    # some class specific attributes and methods

    def refresh(self):
        # implementation
        pass

class ObjB:
    # some class specific attributes and methods

    def refresh(self):
        # implementation
        pass

e hanno tutti un metodo refresh . Ora ho un task manager (come Luigi) che è usato per chiamare il metodo refresh su ogni classe e le definizioni assomigliano a:

from somewhere import ObjA, ObjB


class RefreshObjA(TaskManager):
    def run(self):
        ObjA.refresh()


class RefreshObjB(TaskManager):
    def run(self):
        ObjB.refresh()

TaskManager qui è una classe genitore fornita dal modulo gestore. Come puoi vedere, le definizioni di classe hanno tutte un modello identico e una convenzione di denominazione, ed è ovvio che queste possono essere generate dinamicamente come generateRefreshClasses([ObjA, ObjB, ...]) .

Tuttavia, ho resistito a questa situazione e ne ho scritto esplicitamente ciascuno perché

  • Tutte le informazioni su: le classi sono disponibili quando il codice è scritto, cioè non sono dipendente da nessun input esterno / generato dall'utente, probabilmente in cui la generazione dinamica è utile. Questo uso è puramente per risparmiare spazio / combinazioni di tasti / ripetizioni.
  • Non si sa se un po 'di ObjX potrebbe richiedere modifiche / requisiti aggiuntivi e sarà necessario fare attenzione a rimuoverlo dal generatore dinamico, affinché non venga sovrascritto.
  • È più difficile ragionare dove (come nel file e nella riga no :) si verifica un errore di esecuzione se il codice viene generato dinamicamente.
  • Queste classi potrebbero essere importate altrove nella base di codice e io perdo il controllo basato sull'ispezione statica fornito dall'IDE.

Sono questi validi motivi per continuare a definire individualmente le classi (potrebbero esserci circa 20 o più di esse) o ci sono altri benefici per la generazione dinamica che potrebbero rendere questi problemi piccoli in confronto? La generazione dinamica di classi dovrebbe essere considerata accettabile / buona pratica in tale applicazione?

    
posta user154706 24.12.2014 - 18:42
fonte

1 risposta

1

Sembra che tu abbia un apprezzamento per i trade-off qui coinvolti. Come dici tu, dato che conosci tutte le informazioni sulle tue lezioni in anticipo, non ha senso generarle dinamicamente.

Un'alternativa per ridurre il noioso codice duplicato è quello di usare il meraviglioso supporto di Python per metaprogramming . Se tutti i tuoi metodi refresh seguono un modello simile ma i dettagli variano a causa dei nomi e dei tipi degli attributi delle tue classi, ha senso utilizzare una metaclasse per generare questo metodo quando viene creata la classe. In altre parole, mantieni le tue istruzioni class e dichiari ancora staticamente i membri della tua classe nel codice, ma le informazioni sul refresh boilerplate sono conservate in un unico posto (nel modello utilizzato dal metaclass). ( potresti ottenere lo stesso effetto usando una normale classe base e introspezione, senza ulteriori dettagli sul tuo codice, non posso fornirti una valutazione chiara di quale approccio sarebbe adatto al tuo problema. )

Una seconda opzione sarebbe utilizzare un generatore di codice. Questo di solito assume la forma di uno script che prende (per esempio) alcuni XML o YAML che definiscono i tuoi oggetti come input e scrive un file Python valido nella tua directory di build. Non controllare il codice generato nel controllo del codice sorgente; invece basta eseguire lo script del generatore ogni volta che si crea il codice. In questo modo si ottengono ancora le informazioni sui file / linee durante il debug e il codice risultante non è in genere troppo difficile da capire perché è per lo più standard. D'altra parte, non è possibile modificare direttamente il file una volta diagnosticato un problema perché verrà sovrascritto la prossima volta che si esegue una generazione: è necessario modificare il generatore. Quindi questo approccio ha ancora molti dei vantaggi e degli svantaggi della creazione della classe di runtime completa.

Un'altra domanda che dovresti considerare è "Dobbiamo veramente sapere tutto su questi oggetti in anticipo?". 20 classi simili sono molte e mi suggerisce che una modifica delle esigenze future potrebbe in effetti richiedere il caricamento di queste classi in fase di runtime. Mentre ovviamente dovresti seguire YAGNI, puoi ancora progettare il tuo codice in modo tale che questo cambiamento sia facile da fare in futuro. Questo è un altro modo in cui la metaprogrammazione può aiutarti.

    
risposta data 25.12.2014 - 21:49
fonte

Leggi altre domande sui tag