2010-10-31 12 views
7

Groovy ha una bella operatore per il dereferenziazione sicura, che aiuta ad evitare NullPointerExceptions:dereferenziazione sicuro in Python

variable?.method() 

Il method sarà chiamato solo se variable non è null.

C'è un modo per fare lo stesso in Python? O devo scrivere if variable: variable.method()?

+1

@deamon: prima di tutto non so Groovy e io non voglio discutere su quello che non so, ma questa funzione (dopo che ho letto su di esso ora) non mi sembra utile (e potrei sbagliarmi e il più delle volte lo sono) perché anche se faccio qualcosa del genere __variable.?method()__ yes sure se la variabile è NULL non sta generando un errore ma come fare so che il metodo è stato chiamato, perché mi sembra un errore di silenzio (in realtà non ho mai avuto bisogno di qualcosa di simile prima) e se faccio qualcosa di simile __a = variable.?method()__ quindi dopo dovrei fare __if (a) __ quindi ..., mi sono perso qualcosa :) – mouad

+1

Sono d'accordo con la singolarità; Non vedo come tutto ciò possa essere utile. Sembra qualcosa che potresti spargere sul tuo codice per nascondere gli errori. – adw

+0

@Seth Johnson: puoi essere più specifico, ho detto qualcosa di sbagliato e se riguarda il mio inglese è così male? non è la mia prima lingua :) – mouad

risposta

10
  1. No, non c'è.

  2. Ma per verificare None, non si scrive if x:, si scrive if x is None:. Questo è un importante distinzione - x viene valutato come False per parecchi valori che sono propably perfettamente valido (più considerevolmente 0 equivalente numeri e collezioni vuoto), considerando che x is Nonesolo viene valutato come True se il riferimento x punti all'oggetto singleton None .

  3. Per esperienza personale, tale operatore sarebbe necessario molto raramente. Sì, a volte viene utilizzato None per indicare alcun valore. Ma in qualche modo - forse perché il codice idiomatico restituisce null objects laddove è sensato o genera eccezioni per indicare un errore critico - Ricevo solo un AttributeError: 'NoneType' object has no attribute '...' due volte al mese.

  4. Direi che potrebbe essere una disfunzione. null ha due significati: "ha dimenticato di inizializzare" e "nessun dato". Il primo è un errore e dovrebbe generare un'eccezione. Il secondo caso di solito richiede una gestione più elaborata di "non chiamiamo questo metodo". Quando chiedo al database/ORM per un UserProfile, non c'è e ottengo invece null ... voglio saltare in silenzio il resto del metodo? O voglio davvero (quando in "codice libreria") lanciare un'eccezione approriata (quindi "l'utente (codice)" sa che l'utente non è lì e può reagire ... o ignorarlo) o (quando sono codifica di una funzione specifica) mostra un messaggio sensato ("Quell'utente non esiste, non puoi aggiungerlo alla tua lista amici") all'utente?

3

Python non ha niente del genere. Questo perché non esiste un puntatore null in Python. Bene, c'è il valore speciale None, che è spesso usato in situazioni, dove rappresenta "nessun valore". Ma questa è solo una convenzione. None è un valore/oggetto come tutti gli altri. E dal momento che non esiste lo null, non esiste un operatore che lo gestisca.

+1

Sono d'accordo, ma "Nessuno" è essenzialmente lo stesso in questo caso. Invece di un 'NullPointerException' otterrei un' AttributeError', ma non potrei chiamare un metodo su 'None' che sarebbe presente in un oggetto normale come una lista. – deamon

+1

Il punto è che "Nessuno" non è affatto "insolito". È un oggetto con una classe appropriata, ha metodi, ecc.Non c'è niente nella lingua che lo renderebbe speciale in alcun modo (inoltre, è usato per rappresentare il valore "niente di interessante qui"). Quindi, per cosa sarebbe l'ipotetico "?." Test? Per "Nessuno" in particolare? Che dire di altre librerie che usano altri marcatori (ad esempio, 'NOT_FOUND' in PEAK)? – Dirk

+2

'None' è ottimo per contrassegnare argomenti di funzioni opzionali e varie altre cose, ma usarlo (o qualcosa come' NOT_FOUND') come risultato "non trovato" o altro valore di ritorno speciale dovrebbe essere evitato. L'utilizzo di eccezioni per questo tipo di condizioni eccezionali è migliore perché tende a semplificare il codice utilizzando tali funzioni (invece di controllare ogni valore restituito, è possibile avere una clausola except, o lasciare semplicemente scoppiare l'eccezione). – adw

3

Un linguaggio ho visto e utilizzato è callable(func) and func(a, b, c) in luogo di una chiamata di funzione unita (dove il valore di ritorno non è utilizzato). Se si sta tentando di utilizzare il valore restituito, tuttavia, questo idioma produrrà False se la funzione non è richiamabile, il che potrebbe non essere ciò che si desidera. In questo caso è possibile utilizzare l'operatore ternario per fornire un valore predefinito. Ad esempio, se la funzione restituisce un elenco su cui si eseguirà l'iterazione, è possibile utilizzare un elenco vuoto come valore predefinito con func(a, b, c) if callable(func) else [].

2

Ho usato questa funzione in Groovy, quindi non ripeterò il blasone paradosso di altri poster.

In Groovy una dichiarazione come questa

if(possiblyNull?.value){ 
    ... 

fa questo in Python

try: 
    testVar = possiblyNull.value 
except: 
    testVar = None 
if(testVar): 

E 'sicuramente una caratteristica fredda in Groovy, ed è utile per eliminare il rumore sintattica. Ci sono alcuni altri bit di zucchero sintattico, come l'operatore Elvis o *, ma sacrificano la leggibilità come la spesa per i simboli di correzione rapida (in altre parole, non sono Pythonic).

Speranza che aiuta :-)

Problemi correlati