2016-04-11 2 views
6

Я пытаюсь понять этот код из чужого проекта. Если вы хотите контекст это здесь: https://github.com/newsapps/beeswithmachineguns/blob/master/beeswithmachineguns/bees.py#L501Назначение строки с булевым выражением

IS_PY2 просто булева переменный, True если Python основной версия 2. Я знаю, что непустая строка True, но по какой-то причине я не понимаю openmode присваивается либо 'w', либо 'wt', а не True или False.

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

Может ли кто-нибудь объяснить результат?

ответ

7

Тройная логическое выражение работает как:

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

Таким образом, это выражение:

openmode = IS_PY2 and 'w' or 'wt' 

Стать в Python 2:

openmode = True and 'w' or 'wt' 

что эквивалентно

openmode = 'w' or 'wt' 

Итак, я даю w.

Под Python 3, IS_PY2 ложна, что дает:

openmode = False and 'w' or 'wt' 

что эквивалентно

openmode = False or 'wt' 

Предоставление wt.


Все это является явным указать, что OpenMode для текстовых файлов, а не бинарный, который обозначается w в python2 и wt в Python3.

Хотя режим Python3 t является стандартным, это не обязательно для его точного определения.

См. this answer about wt mode.


Наконец, я думаю, что следующий гораздо более удобным для чтения:

openmode = 'w' if IS_PY2 else 'wt' 

И это один, гораздо более простой:

openmode = 'w' 
10

and и or операторы не просто выполняют логическую операцию над своими операндами, давая логический результат. В результате они дают всегда один из своих операндов. Эти операторы оценивают слева направо, причем and имеют более высокий приоритет, чем or, и они короткозамкнуты, что означает, что они перестают оценивать свои операнды как можно скорее.

В чистой булевой логике, False and x не False, независимо от того, что x есть, так что нет необходимости рассматривать x. Выражение Python False and x даст результат False и не будет пытаться оценить x. Таким образом, False and some_function() будет не позвонить some_function().

Аналогично, True and x в чистой булевой логике будет иметь то же значение, как истина x, то есть, если x является True то True and x является True, в противном случае его False.

Но оператор Python and может обрабатывать произвольные операнды.

В a and b, если a ложно-МОГ, то b не будет оценен и результат будет a. Если a истинно-ish, то bбудет оцениваться и становиться результатом.

Вот краткий демо, с помощью 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 

выхода

False 
0 

[] 

boolean 
integer 
string 
list 

False 
0 

[] 

(Эти пустые строки между 0 и [] находятся там, где пустая строка выходит в печатном виде).

Аналогичные соображения относятся к оператору or.

В чистой булевой логике, True or x не True, независимо от того, что x так, если первая часть or выражения True-иш нам не нужно, чтобы оценить вторую часть. И False or x имеет значение истинности 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 

выход

boolean 
integer 
string 
list 

True 
7 
a 
[42] 

False 
0 

[] 

Как я уже говорил ранее, эти операторы вычисляются слева направо, и мы можем приковать их, если мы хотим. Вот "классические" случаи:

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

Эти утверждения эквивалентны

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

выход

yes 
no 

Это строительство было распространено в более ранних версиях Python.В эти дни, это гораздо более распространенное явление, чтобы увидеть if выражения:

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

, который обычно считается более удобными для чтения, чем тройном выражения с использованием and и or. Кроме того, a and b or c является не эквивалентом b if a else c, если b является ложным.

Однако, все же важно понять, как работает эта тройная работа and ... or, особенно если вам нужно прочитать или сохранить старый код. И некоторые старые Pythonistas по-прежнему предпочитают форму and ... or, так как она немного короче, даже если она немного сбивает с толку, когда вы не понимаете, как это работает. :)

Смежные вопросы