Назначение строки с логическим выражением [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
форма, так как она немного короче, даже если это немного сбивает с толку, когда вы не понимаете, как это работает. :)