2016-04-11 12 views
6

Próbuję zrozumieć ten kod z projektu innej osoby. Jeśli chcesz kontekst to tutaj: https://github.com/newsapps/beeswithmachineguns/blob/master/beeswithmachineguns/bees.py#L501Przypisywanie łańcucha znaków z wyrażeniem boolowskim

IS_PY2 jest tylko zmienna logiczna, True jeśli głównym wersja Pythona to 2. wiem, że niepusty ciąg jest True, ale z jakiegoś powodu nie rozumiem openmode jest przypisane albo 'w' lub 'wt' zamiast True lub False.

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

Czy ktoś mógłby wyjaśnić wynik?

Odpowiedz

7

Trójskładnikowy wyrażenie logiczne pracuje jako:

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

Tak, to wyrażenie:

openmode = IS_PY2 and 'w' or 'wt' 

Zostań w Pythonie 2:

openmode = True and 'w' or 'wt' 

co jest równoważne

openmode = 'w' or 'wt' 

Tak, daję w.

Pod Python 3, IS_PY2 jest fałszywy, podając:

openmode = False and 'w' or 'wt' 

co jest równoważne

openmode = False or 'wt' 

Nadanie wt.


Wszystko to jest jawnie określić, że openmode jest dla plików tekstowych, a nie binarny, który jest wskazany przez w w python2 i wt w Python3.

Tryb domyślny Python3 t nie wymaga precyzowania.

Zobacz this answer about wt mode.


Wreszcie myślę, że następujące jest znacznie bardziej czytelny:

openmode = 'w' if IS_PY2 else 'wt' 

I ten jeden, o wiele bardziej prosta:

openmode = 'w' 
10

and i or operatorzy nie wystarczy wykonać operację boolowską na swoich operandach, dając wynik boolowski. Rezultatem, jaki dają, jest zawsze jeden z ich argumentów. Operatory te oceniają od lewej do prawej, z and mającym wyższy priorytet niż or i powodują zwarcie, co oznacza, że ​​przestają oceniać swoje operandy tak szybko, jak to możliwe.

W czystej logice logicznej False and x to False, bez względu na to, co jest x, więc nie ma potrzeby sprawdzania x. Wyrażenie Python False and x da wynik False i nie będzie próbować ocenić x. Tak więc False and some_function() nie będzie można uzyskać połączenia telefonicznego.

Podobnie True and x w czystej operatory logiczne będą miały taką samą wartość prawdy x, to znaczy, jeśli x jest True następnie True and x jest True, poza jego False.

Jednak operator Python and może obsługiwać dowolne operandy.

W a and b jeśli a jest fałszywa-owski, a następnie b nie będą oceniane, a wynik będzie a. Jeśli a jest prawdziwe-ish, wówczas zostanie ocenione i stanie się wynikiem.

Oto krótkie demo, używając 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 

wyjście

False 
0 

[] 

boolean 
integer 
string 
list 

False 
0 

[] 

(te puste wiersze między 0 i [] są gdzie pusty ciąg jest drukowany uzyskiwanie).

Podobne uwagi dotyczą operatora or.

W czystej logiki logiczną, True or x jest True, bez względu na to co x jest więc jeśli pierwsza część wyrazu or jest True-owski nie musimy ocenić drugą część. I False or x ma wartość prawdy 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 

wyjście

boolean 
integer 
string 
list 

True 
7 
a 
[42] 

False 
0 

[] 

Jak powiedziałem wcześniej, te podmioty są oceniane od lewej do prawej, i możemy je łańcuch, jeśli chcemy. Oto "klasyczne" przypadki:

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

Stwierdzenia te są równoważne

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

wyjściu

yes 
no 

że budowa była powszechna we wczesnych wersjach Pythona.Te dni, to jest znacznie bardziej powszechne, aby zobaczyć if wyraz:

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

który jest powszechnie uważany za bardziej czytelne niż potrójnego wyrażeniu and i or. Ponadto, a and b or c jest , a nie równoważne b if a else c, jeśli b jest fałszywe-ish.

Jednak nadal ważne jest, aby zrozumieć, jak działa ten trójskładnikowy kod: and ... or, zwłaszcza jeśli musisz przeczytać lub zachować starszy kod. A niektóre stare Pythonistas nadal wolą formę and ... or, ponieważ są nieco krótsze, nawet jeśli są trochę oszałamiające, gdy nie rozumiesz, jak to działa. :)

Powiązane problemy