Назначение строки с логическим выражением [duplicate]

этот вопрос уже есть ответ здесь:

Я пытаюсь понять этот код из чужого проекта. Если вы хотите контекст, он здесь: 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': ''}

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

2 ответов


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

>>> 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 в Питон3.

пока Питон3 t режим по умолчанию, это не обязательно точны.

посмотреть это ответ про wt режим.


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

openmode = 'w' if IS_PY2 else 'wt'

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

openmode = 'w'

на 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 is True затем True and x is True, иначе False.

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

на a and b если a ложно-иш, тогда b не будет оцениваться, и результат будет a. Если a верно-иш, тогда 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 is True, несмотря ни на что x так, если первая часть or выражение True-ish нам не нужно оценивать вторую часть. И 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 is не эквивалентно b if a else c если b ложно-иш.

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