Is it pythonic to use properties to limit the mutability of class attributes (variables and methods)?
Per attributi / proprietà / variabili a livello di classe o di istanza: sì, assolutamente! Il decoratore @property è costruito specificamente per dare il controllo su lettura, scrittura ed eliminazione. I casi di utilizzo comune includono:
- imposizione di sola lettura o solo scrittura
- assicurando valori validi
- garantire coerenza con altri stati
- presenta uno stato interno limitato in più modi
- attivazione di altra logica di sistema
- persistenza
Ma in realtà il più autorevole che riesco a ottenere è di citare PEP-8, la guida in stile Python.
With this in mind, here are the Pythonic guidelines:
...
- For simple public data attributes, it is best to expose just the attribute name, without complicated accessor/mutator methods. Keep in mind that Python provides an easy path to future enhancement, should you find that a simple data attribute needs to grow functional behavior. In that case, use properties to hide functional implementation behind simple data attribute access syntax.
Per i metodi: no, non proprio. La maggior parte degli usi di cui sopra non si applica in genere a metodi o funzioni. È certamente possibile sovrascriverli dinamicamente a livello di classe o di oggetto, ma non è comunemente necessario. Fare ciò può certamente essere ok, ma è abbastanza inusuale che porta sempre un esame più attento.
- Is there any reason why I shouldn't be doing this?
Il primo è la leggibilità. Non c'è motivo di fare una linea di codice ovvia in sei linee di lamiera, solo così puoi avere getter e setter passanti. Python (per fortuna!) È stato progettato in modo che il codice chiamante non abbia idea se un attributo sia un attributo raw o una proprietà. Ciò significa che puoi cambiarlo ogni volta che è conveniente per te, invece di essere bloccato nella decisione.
Il secondo è la leggibilità. Per il metodo che nasconde la proprietà, non c'è molto valore aggiunto, e quello stile non è idiomatico. Ci vuole molto più sforzo per capire cosa sta succedendo in primo luogo. È anche imbarazzante in seguito quando il metodo che pensi di chiamare è chiamato qualcos'altro.
Terzo è convenzione. Osservando specificamente la tua nota su pubblico / privato, sembra che tu voglia un modo per marcare cose pubbliche o private. Ma nel tuo esempio di codice, stai già utilizzando correttamente un singolo trattino basso per indicare il contenuto privato. Come promemoria, è possibile ottenere i nomi privati semplicemente facendo riferimento ad essi. È considerato come usato a proprio rischio.
Il quarto è un segnaposto per mostrare quanto sono importanti cinque.
Il quinto è la performance. Questo non è quasi certamente la fonte di alcun problema di prestazioni, ma tecnicamente c'è una leggera penalizzazione delle prestazioni per l'utilizzo di una proprietà. È minuscolo e non dovresti preoccuparti di questo a meno che il tuo profiler non lo abbia misurato ed è assolutamente certo che questo è il problema. Non lo è.
- If not, is it pythonic and why/why not?
Per riassumere, sono assolutamente d'accordo con lo Zen di Python "Semplice è meglio che complesso."