2016-04-11 19 views
6

Sto cercando di capire questo codice dal progetto di qualcun altro. Se si desidera che il contesto è qui: https://github.com/newsapps/beeswithmachineguns/blob/master/beeswithmachineguns/bees.py#L501Assegnazione di una stringa con espressione booleana

IS_PY2 è solo una variabile booleana, True se la versione principale Python è 2. so che una stringa non vuota è True, ma per qualche motivo non capisco openmode assegnato a 'w' o 'wt' anziché a True o False.

openmode = IS_PY2 and 'w' or 'wt' 
openkwargs = IS_PY2 and {} or {'encoding': 'utf-8', 'newline': ''} 

Qualcuno potrebbe spiegare il risultato?

risposta

7

L'espressione booleana ternario funziona come:

>>> 2 and 3 or 4 
3 
>>> 0 and 3 or 4 
4 

Quindi, questa espressione:

openmode = IS_PY2 and 'w' or 'wt' 

Diventa in Python 2:

openmode = True and 'w' or 'wt' 

che equivale a

openmode = 'w' or 'wt' 

Quindi, ho dato w.

In Python 3, IS_PY2 è falso, dando:

openmode = False and 'w' or 'wt' 

che equivale a

openmode = False or 'wt' 

Dare wt.


Tutto questo è per specificare esplicitamente che l'openMode è per i file di testo, non binario, che è indicata da w in python2 e wt in python3.

Mentre la modalità Python3 t è quella predefinita, non è necessario determinarla.

Vedere this answer about wt mode.


Infine, penso che la seguente è molto più leggibile:

openmode = 'w' if IS_PY2 else 'wt' 

E questo, molto più semplice:

openmode = 'w' 
10

Il and e or operatori no esegui semplicemente un'operazione booleana sui loro operandi, dando un risultato booleano. Il risultato che danno è sempre uno dei loro operandi. Questi operatori valutano da sinistra a destra, con and con una precedenza più alta di or e cortocircuitano, il che significa che smettono di valutare i propri operandi il prima possibile.

Nella logica booleana pura, False and x è False, non importa quale x è, quindi non c'è bisogno di esaminare x. L'espressione Python False and x darà un risultato di False e non tenterà di valutare x. Pertanto False and some_function() sarà non chiamata some_function().

Analogamente, True and x in logica booleana puro avrà lo stesso valore di verità come x, cioè, se x è True poi True and x è True, altrimenti è False.

Ma l'operatore Python and può gestire operandi arbitrari.

In a and b se a è falso-ish, quindi b non sarà valutata e il risultato saranno a. Se a è true-ish, allora bsarà essere valutato e diventare il risultato.

Ecco un breve demo, utilizzando Python 2:

print False and 'boolean' 
print 0 and 'integer' 
print '' and 'string' 
print [] and 'list' 
print 

print True and 'boolean' 
print 7 and 'integer' 
print 'a' and 'string' 
print [42] and 'list' 
print 

print True and False 
print True and 0 
print True and '' 
print True and [] 
print 

uscita

False 
0 

[] 

boolean 
integer 
string 
list 

False 
0 

[] 

(Quelle linee vuote tra 0 e [] sono dove la stringa vuota è sempre stampato).

Considerazioni simili si applicano all'operatore or.

Nella logica booleana pura, True or x è True, non importa quale x è così se la prima parte di un or espressione è True-ish non abbiamo bisogno di valutare la seconda parte. E False or x ha il valore di verità di x.

print False or 'boolean' 
print 0 or 'integer' 
print '' or 'string' 
print [] or 'list' 
print 

print True or 'boolean' 
print 7 or 'integer' 
print 'a' or 'string' 
print [42] or 'list' 
print 

print False or False 
print False or 0 
print False or '' 
print False or [] 
print 

uscita

boolean 
integer 
string 
list 

True 
7 
a 
[42] 

False 
0 

[] 

Come ho detto prima, questi operatori vengono valutati da sinistra a destra, e noi li può catena se vogliamo. Qui ci sono i casi "classici":

print True and 'yes' or 'no' 
print False and 'yes' or 'no' 

Tali dichiarazioni sono equivalenti a

print (True and 'yes') or 'no' 
print (False and 'yes') or 'no' 

uscita

yes 
no 

che la costruzione era comune nelle prime versioni di Python.In questi giorni, è molto più comune vedere un if espressione:

print 'yes' if True else 'no' 
print 'yes' if False else 'no' 

che è generalmente considerato più leggibile che l'espressione ternaria utilizzando and e or. Inoltre, a and b or c è non equivalente a b if a else c se b è falso-ish.

Tuttavia, è ancora importante capire come funziona questa cosa ternaria and ... or, soprattutto se è necessario leggere o mantenere il codice precedente. E alcuni vecchi Pythonistas preferiscono ancora il modulo and ... or, poiché è leggermente più corto anche se è un po 'sconcertante quando non capisci come funziona. :)

Problemi correlati