Problema
Sto lavorando a un progetto Python la cui classe principale è un po '" God Object ". Ci sono così tanti e svariati attributi e metodi!
Voglio riformattare la classe.
Finora…
Per il primo passo, voglio fare qualcosa di relativamente semplice; ma quando ho provato l'approccio più semplice, ho rotto alcuni test ed esempi esistenti.
Fondamentalmente, la classe ha un elenco di attributi minuzioso, ma posso chiaramente guardarli e pensare: "Questi 5 attributi sono correlati ... Questi 8 sono anche correlati ... e poi c'è il resto."
getattr
In pratica, volevo solo raggruppare gli attributi correlati in una classe di supporto simile a una dettatura. Ho avuto la sensazione che __getattr__
sarebbe l'ideale per il lavoro. Quindi ho spostato gli attributi in una classe separata e, abbastanza sicuro, ha __getattr__
funzionato perfettamente la sua magia ...
Alla prima .
Ma poi ho provato a eseguire uno degli esempi. La sottoclasse di esempio tenta di impostare direttamente uno di questi attributi (a livello di classe ). Ma poiché l'attributo non era più "localizzato fisicamente" nella classe genitore, ho ricevuto un errore che diceva che l'attributo non esisteva.
@proprietà
Poi ho letto del @property
decoratore. Ma poi ho anche letto che crea problemi per le sottoclassi che vogliono fare self.x = blah
quando x
è una proprietà della classe genitore.
desiderata
- Fai in modo che tutto il codice client continui a funzionare
self.whatever
, anche se lawhatever
proprietà del genitore non si trova "fisicamente" nella classe (o istanza) stessa. - Raggruppare gli attributi correlati in contenitori simili a dict.
- Ridurre l'estrema rumorosità del codice nella classe principale.
Ad esempio, non voglio semplicemente cambiare questo:
larry = 2
curly = 'abcd'
moe = self.doh()
In questo:
larry = something_else('larry')
curly = something_else('curly')
moe = yet_another_thing.moe()
... Perché è ancora rumoroso. Sebbene ciò trasformi con successo un attributo semplice in qualcosa che può gestire i dati, l'originale aveva 3 variabili e la versione ottimizzata ha ancora 3 variabili.
Tuttavia, starei bene con qualcosa del genere:
stooges = Stooges()
E se una ricerca self.larry
non riesce, qualcosa verificherebbe stooges
e vedrebbe se larry
c'è. (Ma deve anche funzionare se una sottoclasse cerca di farlo larry = 'blah'
a livello di classe.)
Sommario
- Desideri sostituire i gruppi di attributi correlati in una classe padre con un singolo attributo che memorizza tutti i dati altrove
- Vuoi lavorare con il codice client esistente che utilizza (ad esempio)
larry = 'blah'
a livello di classe - Desideri continuare a consentire alle sottoclassi di estendere, sovrascrivere e modificare questi attributi refactored senza sapere che nulla è cambiato
È possibile? O sto abbaiando sull'albero sbagliato?