Какой эффект имеет выражение типа "var" и "do_something_with (var)" в Python?

При поиске некоторых ответов в исходном коде пакета (дуршлаг будет конкретным) я наткнулся на строку, которую я не могу понять. Кроме того, мой PyCharm нахмурился: "выражение, похоже, не имеет эффекта".

Вот тезис кода:

...
for path in e.paths():
    keyparts = []
    msgs = []
    for exc in path:
        exc.msg and msgs.extend(exc.messages()) # <-- what is that?
        keyname = exc._keyname()
        keyname and keyparts.append(keyname) # <-- and that
    errors['.'.join(keyparts)] = '; '.join(interpolate(msgs))
return errors
...

Кажется, это очень pythonic, и я хочу осваивать его!

UPD. Итак, поскольку я вижу, что это вообще не pythonic - читаемость вредит ради сокращения.

Ответ 1

Если ключевое имя оценивается как False, оператор and немедленно возвращает false и не оценивает вторую часть. В противном случае он будет оценивать вторую часть (не в этом случае значение возврата). Таким образом, это в основном эквивалентно:

if keyname: 
    keyparts.append(keyname)

Я не уверен, что это очень pythonic, хотя, поскольку версия, которую я только что предложил, выглядела намного более читаемой (по крайней мере, для меня лично).

Ответ 2

and и or short-circuiting логические операторы; что означает, что, как только Python узнает, какой должен быть ответ, он перестает оценивать любые оставшиеся предложения.

В фрагменте, который вы отправили and, используется для защиты функций .extend() и .append() - предположительно, автор не хочет публиковать, например, None в списках.

Я обычно использую эту функцию в операторах if:

if name and name[0] in ('Mr', 'Mrs', 'Ms'):
    ...

name - возможно пустой список - если он пуст, name[0] терпит неудачу с IndexError, поэтому я охраняю его с помощью name and - если name пуст, name[0] ( и блок if) не выполняются и ошибка устранена.

Это очень Pythonic функция.

Ответ 3

Так как в python первое выражение в выражении and оценивается до второго, и интерпретатор выходит из оценки выражения and, если первое выражение False,

keyname and keyparts.append(keyname)

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

if keyname:
    keyparts.append(keyname)