Devo usare le eccezioni per controllare l'intervallo di parametri in Python?

5

Ad esempio per la seguente firma del metodo:

def genClusters(n_clusters, n_nodes, cluster_distribution):

n_clusters dovrebbe essere un numero intero superiore a 1.

n_nodes dovrebbe essere un numero intero superiore a n_clusters

cluster_distribution dovrebbe essere un float compreso tra 0 e 1.

Devo usare una serie di istruzioni if then raise exception per gestire i limiti dei parametri dell'argomento?

es:

def genClusters(n_clusters, n_nodes, cluster_distribution):
    if (cluster_distribution < 0 or cluster_distribution > 1):
        raise ValueError("cluster distribution must be between 0 and 1")
    if n_clusters < 1:
         raise ValueError("n_clusters must be at least 1")
    if n_nodes <= n_clusters:
         raise ValueError("n_nodes must be at least n_clusters")

La seconda domanda è se dovrei includere queste istruzioni di eccezione in ogni metodo che chiama anche questo.

Ad esempio:

def myFoo(foo, bar, bang):
    clusters = genClusters(foo, bar, bang) 

In questo scenario, se foo, bar o bang non si adattano ai limiti di parametri precedentemente definiti, verrà generata un'eccezione quando viene chiamata genClusters . Quindi dovrei anche escludere le eccezioni all'inizio di myFoo ?

    
posta dwjohnston 23.01.2015 - 02:57
fonte

1 risposta

6

Supponiamo di non controllare preventivamente gli argomenti di input e di lasciare che la funzione faccia il suo corso. Considera questo: qual è il peggiore che succederà? (Questa non è una domanda retorica). Sta dando un input negativo andando a:

  • fa fallire la funzione con un'altra eccezione da qualche parte nel codice?
  • perdere un sacco di tempo, quindi fallire a metà strada?
  • fai qualcosa di potenzialmente dannoso (ad esempio, elimina i tuoi dati importanti ...)?
  • restituisce un risultato falso?
  • causa un messaggio di errore confuso?

Considerali attentamente. In la maggior parte degli scenari, in cui le prestazioni non sono della massima importanza, si vuole davvero che fallisca presto e il più a lungo possibile , quindi è generalmente consigliabile cercare argomenti non validi ( spero che risponda alla tua prima domanda).

Questo aiuta a fare il debug e riduce il rischio che il tuo codice faccia qualcosa di terribile. Certo, a volte può essere noioso, quindi se vuoi un approccio rapido (utile per la prototipazione), usa assert :

assert 0 <= cluster_distribution <= 1

Tuttavia, è inutile farlo due volte se è ovvio che un'altra funzione lo farà per te, poiché porterà a una duplicazione del codice non necessaria (si spera che risponda alla tua seconda domanda).

Ad esempio, supponi di avere una (piuttosto inutile) funzione come questa:

def square_root(s);
    return math.sqrt(s)

Non è necessario verificare se s non è negativo perché sqrt lo fa già. Nella maggior parte delle "piccole" funzioni come questa, non è necessario eseguire molti controlli di input. Solitamente, solo le funzioni "grandi" richiedono un controllo di input esplicito come questi. In alcuni casi, puoi ristrutturare il codice senza controlli espliciti in modo che se gli input non sono validi, falliranno automaticamente.

    
risposta data 23.01.2015 - 04:00
fonte

Leggi altre domande sui tag