Esempi pratici
In Python, l’iterazione ci consente di esaminare un elenco di elementi per eseguire operazioni particolari. Un modo comune per creare un’iterazione è utilizzare i loop for
, che hanno il seguente formato generale.
for i in iterable:
expression
Come discusso nel mio precedente articolo, possiamo creare i nostri iteratori personalizzati che possono essere utilizzati come iterabili nei loop for
. Per soddisfare il “duck testing” per gli iteratori, la classe personalizzata deve implementare i metodi __iter__()
e __next__()
. Un esempio specifico è riportato di seguito.
Nello snippet di codice sopra, abbiamo implementato entrambi i metodi __iter__()
e __next__()
che rendono le istanze della classe personalizzata Cubes
iteratori, in modo tale che l’istanza potesse essere utilizzata in un ciclo for
.
Callables
Oltre al tipo di dati dict
incorporato, un altro tipo di dizionario importante è defaultdict
, disponibile nel modulo collections
. Questo tipo di dati simile a un dizionario ha il seguente costruttore: defaultdict(])
. In particolare, l’argomento default_factory
è un tipo di callable, come una funzione o una funzione lambda.
Nel mio precedente articolo, ho mostrato che potevamo utilizzare defaultdict
passando una funzione lambda. Ecco l’esempio del suo utilizzo.
>>> from collections import defaultdict
>>> letter_counts = defaultdict(lambda: 0)
>>> for i in 'abcddddeeeee':
... letter_counts += 1
...
>>> letter_counts.items()
dict_items()
In particolare, possiamo avere una migliore flessibilità per utilizzare il tipo di dati defaultdict
se creiamo la nostra fabbrica predefinita. Con la filosofia “duck typing”, la classe personalizzata deve implementare il metodo __call__()
, che è quello di rendere qualcosa chiamabile. Vediamo come funziona.
Come mostrato nel codice precedente, creiamo la classe DucklingFactory
, la cui funzione __call__()
restituisce un elenco di un’istanza Duckling
. Usando questa funzione di fabbrica, saremo in grado di fare il numero desiderato di anatroccoli moltiplicando l’elenco di anatroccoli predefinito.
Ordinamento con Len ()
Un altro possibile utilizzo della digitazione duck è implementare la funzione personalizzata len()
, che può essere utilizzata per ordinare un elenco utilizzando la funzione sort()
. Come nota a margine, alcune persone si riferiscono alla funzione len()
come una funzione magica, perché è implementata chiamando la funzione __len__()
dietro le quinte (quelle funzioni con doppi caratteri di sottolineatura come prefisso e suffisso sono chiamate funzioni magiche).
Supponiamo di voler ordinare un elenco di anatre in base alla lunghezza del nome di ogni anatra. Ecco come possiamo applicare la digitazione anatra in questo caso.
Nello snippet di codice precedente, la classe custom NamedDuck
implementa le funzioni __str__()
e __len__()
, che ci consentono di utilizzare le funzioni str()
e len()
sulle sue istanze nelle righe 10 e 12, rispettivamente. È importante sottolineare che, come puoi vedere, sebbene l’elenco sia mescolato con anatre e stringhe denominate, tutti gli elementi possono chiamare le funzioni str()
e len()
, in modo tale che l’elenco possa essere ordinato usando len()
come chiave e usato nella comprensione dell’elenco quando vogliamo stampare il risultato ordinato.
Pertanto, l’implicazione più ampia di questo utilizzo è che quando abbiamo un elenco misto di elementi di diversi tipi di dati, purché ogni tipo di dati implementi le stesse funzioni, gli elementi passeranno il test duck e saranno applicati con le operazioni corrette. Ecco un esempio di caso d’uso generale utilizzando la funzione len() su un elenco misto di tipi di dati di str
, tuple
e list
.
>>> mixed_list = ]
>>> mixed_list.sort(key=len)
>>> mixed_list
, (1, 2), 'Amazing']