Бы быть подходящие для Python, чтобы использовать `или`, подобно тому, как в PHP использовать `или умереть()`?
Это подходящие для Python, чтобы использовать or
, Подобно тому, как в PHP могла бы использовать or die()
?
Я используюquiet or print(stuff)
вместо того, чтобыif verbose:
print(stuff)
недавно.
or
2 0 LOAD_FAST 0 (quiet)
3 JUMP_IF_TRUE_OR_POP 15
6 LOAD_GLOBAL 0 (print)
9 LOAD_CONST 1 ('foo')
12 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
>> 15 POP_TOP
16 LOAD_CONST 0 (None)
19 RETURN_VALUE
Vs if
2 0 LOAD_FAST 0 (verbose)
3 POP_JUMP_IF_FALSE 19
3 6 LOAD_GLOBAL 0 (print)
9 LOAD_CONST 1 ('bar')
12 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
15 POP_TOP
16 JUMP_FORWARD 0 (to 19)
>> 19 LOAD_CONST 0 (None)
22 RETURN_VALUE
2 ответа:
Нет, это определенно не питон. Многие из решений, принятых на этом пути, были специально направлены на то, чтобы препятствовать такого рода кодированию.
Правильный способ написать это очевидный способ:
if verbose: print(stuff)
Или, если вычисление
stuff
само по себе не дорого / опасно/безотзывно, просто обернитеdef printv(*args, **kwargs): if verbose: print(*args, **kwargs)
... так что вы можете просто сделать это, что примерно так кратко, как вы собираетесь получить:
printv(stuff)
Или, еще лучше, использовать
logging
модуль вместо изобретения колеса.
Но что делать, еслиstuff
стоит дорого, и вы действительно хотите сохранить строку?Ну, вам, вероятно, на самом деле не нужно сохранять строку, и это всегда приносит в жертву читабельность для краткости; "читабельность считается" - ключевая частьДзен Python . Но Python позволяет поместить однострочный набор на ту же строку, что и условие:
if verbose: print(stuff)
Как говорит PEP 8 , " иногда это ладно", но это "вообще обескураживает". Как выразился Гвидо в письме из списка рассылки ideas, "Если вам нужно сохранить строку, используйте однострочный оператор if, а не что-то "умное". Но если вы должны сохранить строку, я, вероятно, не хочу читать ваш код."
Если вы хотите этого в выражении (которое вы не должны, как я объясню ниже), или вы хотите технически следовать PEP 8 до буквы, грубо нарушая дух:
print(stuff) if verbose else None
Итак, что же не так Питон об этом?
Во-первых, вы используете результат
И вообще, Python имеет только один побочный эффект на строку, и это происходит как можно дальше влево, что позволяет легко просматривать код и видеть, что меняется. Это усиливается сильным разделением между высказываниями и выражениями (и, например, присваиваниями, являющимися высказываниями). методы с побочными эффектами, идиоматически возвращающие
Но даже игнорирование всего этого, использованиеNone
вместоself
, и так далее.and
иor
только для короткого замыкания, а не для их результатов, потенциально сбивает с толку и, по крайней мере, в сознании некоторых людей, уродливо. Вот почему было добавлено тернарное выражение (spam if eggs else beans
): чтобы люди перестали писатьeggs and spam or beans
. Почему это сбивает с толку? Во-первых, он вообще не читается как английский, если только вы не читали больше кода Perl, чем настоящий английский. Во-вторых, очень легко случайно использовать допустимое значение, которое оказывается ложным; вы знаете, что этого делать не следует, и проверить это, когда вы видитеif
, но здесь вы этого не делаете. Также обратите внимание, чтоprint(stuff) if verbose else None
делает явным, что вы создаете значение, с которым затем ничего не делаете; явное всегда лучше, чем неявное, но особенно когда вы делаете что-то необычное.
Наконец, что касается производительности: (а) кого это волнует, и (Б) почему бы не измерить ее вместо этого или попытаться угадать, читая байт-код, который вы не понимаете?
In [511]: quiet = True In [512]: %timeit quiet or None 10000000 loops, best of 3: 48.2 ns per loop In [513]: verbose=False In [514]: %timeit if verbose: pass 10000000 loops, best of 3: 38.5 ns per loop
Итак, в случае быстрого прохождения оператор
Если вы хотите знать, почему, ну, вы должны были бы посмотреть на реализацию этих байт-кодов на конкретной версии конкретной реализации, которая вас интересует... но, скорее всего, необходимость сделать дополнительныйif
на самом деле примерно на 20% быстрее, а не медленнее-и они оба настолько быстры, что вряд ли когда-либо повлияют на вашу программу в любом случае. Если вы делаете это миллиард раз в узком цикле и вам нужно выжать эту производительность, вы захотите вытащить остальное из цикла, даже если это означает повторение с двумя почти клонами одного и того же кода (особенно учитывая, что цикл безPOP_TOP
вместо того, чтобы один слился в предыдущую операцию, является частью разницы.