2016-07-09 8 views

risposta

4

ne dite:

s = sb and sb.ToString() 

Il corto circuito booleano si arresta se sb è Falsy, altrimenti ritorna l'espressione successiva.

Btw, se ottenendo Nessuno è importante ...

sb = "" 

#we wont proceed to sb.toString, but the OR will return None here... 
s = (sb or None) and sb.toString() 

print s, type(s) 

uscita:

None <type 'NoneType'> 
+0

Grazie, accetterò questa risposta dopo un po 'se nient'altro. –

+0

Questa soluzione fornisce un risultato inaspettato se sb non è "Nessuna" ma una falsa. Ad esempio se 'sb =" "' questo dà '" "', invece di '" ".method()' – Tanmay

4

Bene, la soluzione più semplice sarebbe:

result = None if obj is None else obj.method() 

Ma se si vuole l'esatto equivalente avente la stessa sicurezza dei thread in qualità di operatore Null-condizionale C# 's, sarebbe:

obj = 'hello' 
temp = obj 
result = None if temp is None else temp.split() 

Il compromesso è che il codice non è molto carino; Anche un nome extra temp viene aggiunto allo spazio dei nomi.

Un altro modo è:

def getattr_safe(obj, attr): 
    return None if obj is None else getattr(obj,attr) 

obj = 'hello' 
result = getattr_safe(obj,'split')() 

Qui, trade-off è la funzione di chiamata in testa, ma il codice molto più chiaro, soprattutto se lo si utilizza più volte.

+2

Grazie, io sono a conoscenza di questo metodo, ma speravo che ci sia un modo più breve per farlo. –

+0

Sfortunatamente, non c'è. Però, puoi avvolgere questo in una funzione, se non ti dispiace il sovraccarico. – Tanmay

+0

Penso che l'esempio di questa risposta richieda una revisione perché ha bisogno di un contesto aggiuntivo - Python non ha il metodo 'ToString' integrato; perché abbiamo bisogno di un ulteriore passaggio con 'temp = sb'? –

0

Ho scritto questa funzione con il comportamento richiesto. Un vantaggio di questo oltre il concatenamento and è che è più facile scrivere quando si tratta di catene lunghe. Guarda questo non funziona con le chiavi dell'oggetto, solo gli attributi.

def null_conditional(start, *chain): 
    current = start 
    for c in chain: 
     current = getattr(current, c, None) 
     if current is None: 
      break 
    return current 

Ecco alcuni test mi sono imbattuto in modo da poter vedere come funziona

class A(object): 
    b = None 
    def __init__(self, v): 
     self.b = v 

class B(object): 
    c = None 
    def __init__(self, v): 
     self.c = v  

a_1 = A(B(2)) 
a_2 = A(None) 
print(null_conditional(a_1, 'b', 'c')) # 2 
print(null_conditional(a_1, 'b', 'd')) # None 
print(null_conditional(a_2, 'b', 'c')) # None 
print(null_conditional(None, 'b')) # None 
print(null_conditional(None, None)) # TypeError: attribute name must be string