Quando Pythonic non usa le proprietà invece di un metodo che non accetta argomenti?

0

È ampiamente riconosciuto che le proprietà di Python sono non solo un guaio per aggirare l'errore del passato di esporre pubblicamente i membri dei dati. Ma allora quando Pythonic non usa una proprietà invece di un metodo che non accetta argomenti?

Ad esempio, se stessimo scrivendo la libreria standard Python da zero, sarebbe più Pythonic sostituire dict.items() con dict.items ? Potremmo anche aggiungere un setter con un comportamento perfettamente intuitivo. Quel si sente sbagliato, ma non posso articolare le regole per quello che è e non è un uso pitonico delle proprietà che squalificherebbe questo uso. Una regola ovvia potrebbe essere che se non c'è un setter ragionevole, le proprietà non dovrebbero essere utilizzate. Questo squalifica dict.values() e dict.keys() ma non dict.items() .

Ovviamente lo stile può essere soggettivo, ma dal momento che è un motto di Python che "Ci dovrebbe essere uno - e preferibilmente solo uno - modo ovvio per farlo.", penso che questa domanda sia ragionevole. Inoltre, proviamo ad attenerci ai PEP e al codice nella libreria standard di Python.

    
posta Praxeolitic 06.03.2018 - 20:15
fonte

2 risposte

4

Questo problema non è specifico di Python, ma è condiviso da qualsiasi linguaggio con proprietà, ad es. C #. E poiché c'è solo differenza sintattica tra getter e proprietà, questa è la stessa domanda se dovremmo usare un metodo getter o un metodo normale.

In generale:

  • Preferisci le proprietà in cui altrimenti avresti usato un metodo getter.
  • Preferisci proprietà / getter quando stai concettualmente accedendo a una proprietà dell'oggetto e non stai dicendo all'oggetto di fare del lavoro. I getter e ancor più le proprietà hanno l'aspettativa di essere veloci e di funzionare in tempo O (1).
  • Preferisci i metodi ordinari se stai dicendo all'oggetto di fare qualcosa, se l'operazione è costosa, o se hai bisogno di fornire argomenti. (Anche se per un singolo argomento, a __getitem__ -interface a volte può essere opportuno nei casi in cui altrimenti si utilizzerà una proprietà.)
  • Se una proprietà è di sola lettura o meno non è di per sé un buon indicatore del fatto che una proprietà o un metodo sarebbe più idiomatico.

Nel caso di un dizionario, questi sono spesso implementati in un modo che consente un'iterazione economica su voci, chiavi e valori. Sarebbe quindi possibile utilizzare dict.items , dict.keys proprietà che restituiscono un iteratore. Questa è in realtà una grande differenza tra Python 2 e 3: in Python 2, tutti restituiscono liste che dovrebbero attraversare tutte le voci con interesse, non solo restituire un oggetto vista a buon mercato come in Python 3. Quindi in Python 2 era un progetto ragionevole utilizzare i metodi. In Python 3 questo è solo un design ragionevole a causa della retrocompatibilità.

Nota che mentre lo "Zen di Python" è un buon obiettivo , non è una buona descrizione per una lingua che ha accumulato un sacco di angoli crudeli e strani negli anni. Come in tutte le cose, dovrai usare il tuo giudizio piuttosto che basarti su un motto vago.

    
risposta data 06.03.2018 - 20:49
fonte
1

Questa domanda è incredibilmente soggettiva, il motto di Python essere dannato, ma penso che ci sia un approccio ragionevole ad esso:

Utilizza le proprietà quando un oggetto deve agire come-se contiene quei membri.

I getter sono intrinsecamente un'area grigia per l'incapsulamento. Tecnicamente incapsulano i dati, ma sono "supposti" per evitare di fare molti calcoli. Dovrebbero agire come-se erano semplicemente membri. Se un particolare pezzo di codice lascia quell'area grigia e diventa in bianco e nero, probabilmente dovrebbe essere un membro di dati o una funzione.

Nel caso di dict.items() , questo è un posto povero per le proprietà. items() crea una nuova lista di tuple. Non usa nulla all'interno del dizionario. Ad esempio, dict.items.append(("foo", "bar")) non aggiunge nulla al dizionario.

Per quanto riguarda "Ci dovrebbe essere uno - e preferibilmente uno solo - modo ovvio per farlo", chiamami eretico, ma Python lo considera come una linea guida, non una regola. Considera concatenazione di stringhe come esempio sorpreso Guido in passato.

    
risposta data 06.03.2018 - 20:44
fonte

Leggi altre domande sui tag