2014-04-17 15 views
33

Se riesco a rilevare uno KeyError, come posso dire quale ricerca non è riuscita?Quale chiave non è riuscita in Python KeyError?

def poijson2xml(location_node, POI_JSON): 
    try: 
    man_json = POI_JSON["FastestMan"] 
    woman_json = POI_JSON["FastestWoman"] 
    except KeyError: 
    # How can I tell what key ("FastestMan" or "FastestWoman") caused the error? 
    LogErrorMessage ("POIJSON2XML", "Can't find mandatory key in JSON") 
+2

Dal momento che si dovrebbe eseguire il branching sulla chiave che ha comunque fallito, è probabilmente più chiaro inserire ogni ricerca in una dichiarazione 'try' separata. – chepner

risposta

52

Prendere l'eccezione corrente (l'ho usato as e in questo caso); quindi per un KeyError il primo argomento è la chiave che ha generato l'eccezione. Quindi possiamo fare:

except KeyError as e: # One would do it as 'KeyError, e:' in Python 2. 
    cause = e.args[0] 

Con questo, si ha la chiave incriminata memorizzata in cause.

Si noti che e.message funziona in Python 2 ma non in Python 3, quindi non deve essere utilizzato.

+2

Grazie. Suppongo che questo non sia documentato da nessuna parte? Non riuscivo a trovarlo nei documenti Python. – QuestionC

+2

@QuestionC ['BaseException.args'] (https://docs.python.org/3.4/library/exceptions.html#BaseException.args) è documentato, ma non in modo sufficientemente dettagliato che i suoi usi sono evidenti. –

-2

Se si importa il modulo sys è possibile ottenere informazioni di eccezione con sys.exc_info()

come questo:

def POIJSON2DOM (location_node, POI_JSON): 
    try: 
    man_JSON = POI_JSON["FastestMan"] 
    woman_JSON = POI_JSON["FastestWoman"] 

    except KeyError: 

    # you can inspect these variables for error information 
    err_type, err_value, err_traceback = sys.exc_info() 

    REDI.LogErrorMessage ("POIJSON2DOM", "Can't find mandatory key in JSON") 
+0

La risposta di @Alex Thornton è molto più semplice e risponde più direttamente alla domanda. A proposito, dal momento che questo è in calo, c'è qualcosa di sbagliato fondamentalmente nel mio approccio? Ho usato questo metodo e mi piacerebbe non usarlo se causa problemi. Aiutami :) – jshanley

+0

Non vedo alcun motivo per il downvote. La sintassi per catturare un'eccezione prima di Python 2.6 era meno chiara, quindi chiamare esplicitamente 'sys.exc_info()' era un approccio ragionevole. – chepner

+2

Non è un downfert, ma: è più complicato di "tranne Foo as e', ed è una condizione di competizione nel codice multithreaded. Cosa succede se due thread generano un KeyError prima che uno di essi possa chiamare 'sys.exc_info'? Entrambi i thread vedrebbero lo stesso risultato, quindi uno di essi potrebbe essere sbagliato. La sintassi 'except Foo as e' è un'operazione atomica. –

2

Non sono sicuro se si sta utilizzando i moduli per assistere l'utente - se il JSON è in arrivo come dict, si può usare dict.get() verso un fine utile.

def POIJSON2DOM (location_node, POI_JSON): 
    man_JSON = POI_JSON.get("FastestMan", 'No Data for fastest man') 
    woman_JSON = POI_JSON.get("FastestWoman", 'No Data for fastest woman') 
    #work with the answers as you see fit 

dict.get() prende due argomenti - il primo è il key si desidera, il secondo è il valore da restituire se quella chiave non esiste.

Problemi correlati