2015-05-06 5 views
1

Есть более простой альтернативой, чемПрисвоить в, если заявление Python

res = returns_value_or_none(arg) 
if res: 
    do_something_with(res) 

или

if returns_value_or_none(arg): 
    do_something_with(returns_value_or_none(arg)) 

One, который сочетает в себе назначение и if условную в одно заявление?

+0

Первый способ у вас в порядке. Просто не забудьте использовать 'if res is None ', если возвращаемое значение может быть некоторым другим допустимым, но ложным значением (например, пустой строкой). – wim

+0

Что вы действительно ищете, это C-style 'if res = spam():' или 'if (ch = getch())! = EOF:', а у Python этого нет. У Python есть веские причины; У Свифта есть разные веские причины; если вы разрабатываете новый язык и, сохраняя одну строку или 5 символов, вполне может стоить, если в противном случае нет веских причин, но в противном случае у вас могут быть веские причины. – abarnert

ответ

2

Часто, у вас есть уже лучший вариант.


Вы всегда можете создать новую область, чтобы связать значение переменной:

(lambda res: do_something_with(res) if res else None)(returns_value_or_none(arg)) 

Но это, конечно, не будет более удобным для чтения, или более Pythonic.


Если вы просто хотите сохранить одну строку, вы можете сделать это:

res = returns_value_or_none(arg) 
if res: do_something_with(res) 

Это более читаемым иногда, но, как правило, это чистый убыток.


Другой способ борьбы с этим было бы изменить do_something_with принимать None и ничего не делать. Это не так часто встречается в Python, как это происходит, скажем, Smalltalk или Swift, но иногда оно имеет свое место.

Трудно понять, почему с подобным примером игрушка, но если вы вызываете эти функции 70 раз, ставя чек в одном месте, внутри функции, а не в 70 местах, везде, где она называется, является очевидная победа. (Тем более, что вы, вероятно, положил его в 68 местах и ​​забыть другой 2.)


последнее, но не менее, во многих случаях правильный ответ исключения. Ваш do_something_with, вероятно, уже поднимается, если вы пройдете None. И вы можете с уверенностью изменить returns_value_or_none на returns_value_or_raises.

Опять же, в этом примере игрушек это будет выглядеть скорее как больше кода. Но в реальном коде часто бывает целесообразно поставить целый блок кода внутри try/except и обрабатывать все ошибки сразу в конце. Или даже позволить исключениям просачиваться на более высокий уровень, с которым легче справиться.

Конечно, это не подходит в каждом случае; если вы ожидаете, что None будет частым и вполне разумным ответом, и просто хотите пропустить один шаг, а не прервать всю цепочку операций, проверка или прохождение через None будет иметь гораздо больше смысла, чем засорять ваш код небольшими try блоки.

+0

Спасибо, я думаю, я с оптимизмом смотрел на синтаксический сахар. Проблема, позволяющая вызываемым функциям принимать None, заключается в том, что в других контекстах я хочу, чтобы одна и та же функция вызывала ошибку, если был получен None или другой недопустимый тип. Кроме того, в большинстве случаев это что-то вроде 'if re.match (some_pattern, text): do_something_with (re.match (some_pattern, text) .group (1))'. Если забудьте условие if, а функция re.match() возвращает None, интерпретатор скоро мне сообщит. – Peter

+0

@Peter: Обычно нет ничего плохого в том, чтобы позволить интерпретатору дать вам знать («означает ли вы» «обработчик' except »в вашем коде или программист, который не учитывал возможность того, что значение может быть« Нет »и, следовательно, не кодировал для него). – abarnert

+0

@Peter: Между тем, если вы покажете нам только бессмысленный пример с игрушкой, вы только получите «вот полдюжины способов сделать похожие вещи, которые подходят в вашем реальном коде, зависит от этого реального кода» ; если вы покажете нам пару реальных примеров, мы можем показать вам идиоматический способ справиться с этими примерами. – abarnert