Ho visto innumerevoli volte il seguente approccio suggerito per "prendere in una collezione di oggetti e fare X se X è una Y e ignorare l'oggetto altrimenti"
def quackAllDucks(ducks):
for duck in ducks:
try:
duck.quack("QUACK")
except AttributeError:
#Not a duck, can't quack, don't worry about it
pass
L'implementazione alternativa di seguito ottiene sempre critiche per il calo di prestazioni causato dal controllo dei tipi
def quackAllDucks(ducks):
for duck in ducks:
if hasattr(duck,"quack"):
duck.quack("QUACK")
Tuttavia, mi sembra che nel 99% degli scenari si desideri utilizzare la seconda soluzione a causa di quanto segue:
- Se l'utente ottiene i parametri errati, essi non verranno trattati come un'anatra e non ci sarà alcuna indicazione. Un sacco di tempo sarà sprecato a debugging perché non c'è ciarlatano in corso fino a quando l'utente non si rende finalmente conto del suo stupido errore. La seconda soluzione genererebbe una traccia dello stack non appena l'utente ha provato a ciarlare.
- Se l'utente ha qualche bug nel loro metodo quack () che causa un AttributeError allora quei bug saranno inghiottiti silenziosamente. Ancora una volta il tempo sarà sprecato a scavare per il bug quando la seconda soluzione darebbe semplicemente una traccia dello stack che mostra il problema immediato.
In effetti, mi sembra che l'unica volta in cui vorresti utilizzare il primo metodo sia quando:
- Il blocco di codice in questione si trova in una sezione estremamente critica delle prestazioni della tua applicazione. Seguendo il principio di "evitare l'ottimizzazione prematura", lo realizzeresti naturalmente, dopo aver implementato un approccio più sicuro e trovato un collo di bottiglia.
- Ci sono molti tipi di oggetti di ciarlatura là fuori e sei interessato solo a ciarlare gli oggetti che sono ciarlatani con un insieme di argomenti molto specifico (questo mi sembra un caso molto raro).
Dato questo, perché così tante persone preferiscono il primo approccio rispetto al secondo approccio? Che cosa mi manca?
Inoltre, mi rendo conto che ci sono altre soluzioni (come l'uso di abcs) ma queste sono le due soluzioni che mi sembrano più frequenti per il caso base.