2010-01-07 3 views
85

У меня есть функция, которая может вернуть один из трех вещей:В Python, как я должен проверить, если переменная является None, Правда или Ложь

  • успех (True)
  • недостаточность (False)
  • ошибка чтения/синтаксического анализа потока (None)

Мой вопрос, если я не должен испытать против True или False, то как Я вижу результат. Ниже, как я сейчас делаю это:

result = simulate(open("myfile")) 
if result == None: 
    print "error parsing stream" 
elif result == True: # shouldn't do this 
    print "result pass" 
else: 
    print "result fail" 

это действительно так просто, как удаление == True части или я должен добавить три-булев тип данных. Я не хочу, чтобы функция simulate выдавала исключение, поскольку все, что я хочу, чтобы внешняя программа выполняла с ошибкой, регистрирует ее и продолжает.

+0

Вы задаете неправильный вопрос; вы должны просить о помощи, определяющей ваш результат ... в чем разница, которую вы воспринимаете между «сбоем» и «потоком анализа ошибок», что они означают, каковы последствия, какое действие вызывает вызывающий абонент, в каждом случае (pass, fail, parse error)? –

+0

Я имитирую электрическую систему, если люди теряют власть в своих домах, это провал. Если я не могу прочитать файл моделирования, то это ошибка совершенно другого вида. –

+0

Непонятно (возможно, потому, что это не очень хорошая идея), почему вы хотите избежать использования исключения, чтобы указать исключительное условие. Что-то убеждало вас в том, что исключения являются «тяжелыми», медленными или имеют какую-то другую проблему для такого рода случаев? Ответ Павла показывает, как это нужно делать с Python. –

ответ

83

Не бойтесь Исключения! После вашей программы просто войти и продолжать так же легко, как:

try: 
    result = simulate(open("myfile")) 
except SimulationException as sim_exc: 
    print "error parsing stream", sim_exc 
else: 
    if result: 
     print "result pass" 
    else: 
     print "result fail" 

# execution continues from here, regardless of exception or not 

И теперь вы можете иметь более богатый тип уведомления от метода SIMULATE относительно того, что именно пошло не так, в случае, если вы не находите ошибки/нет ошибки не быть достаточно информативным.

+0

Согласовано. Гораздо больше pythonic, чем, очевидно, более популярное решение выше (которое сильно пахнет, как C-код). – Brandon

+4

@Brandon Не согласовано. Этот код длиннее и, что еще хуже, менее читабельным, чем вышеприведенное решение (или улучшенная версия ниже): больше отступов, более разных заявлений - угадайте, почему последнее является более популярным, как вы говорите ... ;-) Зачем пытаться быть «Pythonic», если это приведет к более неудобному коду ...? –

+0

Теперь распечатайте трассировку вместо «потока анализа ошибок», и вы получили мой голос. – CivFan

85
if result is None: 
    print "error parsing stream" 
elif result: 
    print "result pass" 
else: 
    print "result fail" 

держите его простым и явным. Конечно, вы можете заранее определить словарь.

messages = {None: 'error', True: 'pass', False: 'fail'} 
print messages[result] 

Если вы планируете модифицируя simulate функцию, чтобы включить больше кодов возврата, поддерживая этот код может стать немного проблема.

simulate также может вызвать исключение при анализе ошибки, и в этом случае вы либо поймаете его здесь, либо позвольте ему распространить уровень вверх, а бит печати будет уменьшен до однострочного оператора if-else ,

+1

Последний - это явное испытание против True или False, не так ли? –

+1

, конечно, но зная, что это только возможные возвращаемые значения, я не думаю, что это проблема. – SilentGhost

+0

и, кажется, немного быстрее, а также – SilentGhost

2

Я считаю, что выбрасывание исключения - лучшая идея для вашей ситуации. Альтернативой будет метод моделирования для возврата кортежа. Первым пунктом будет статус, а второй - результат:

result = simulate(open("myfile")) 
if not result[0]: 
    print "error parsing stream" 
else: 
    ret= result[1] 
+1

возвращение кортежа обычно идет хорошо с распаковкой кортежа;) – SilentGhost

+1

ваш код, однако, не имеет большого смысла, если возвращается «False», он будет печатать '' parsing stream''. – SilentGhost

+0

Метод имитации должен возвращаться (False, «вообще что-либо») или (True, ret), где ret является либо False, либо True. – kgiannakakis

14

Никогда, никогда, никогда не говорят

if something == True: 

Никогда. Это безумие, поскольку вы избыточно повторяете то, что избыточно указано как правило избыточного условия для if-statement.

Хуже того, по-прежнему, никогда, никогда, никогда не говорят

if something == False: 

Вы not. Не стесняйтесь использовать его.

И, наконец, выполнение a == None неэффективно. Do a is None. None - это особый одноэлементный объект, его может быть только один. Просто проверьте, есть ли у вас этот объект.

+0

Я знал, что это плохая идея, поэтому я разместил вопрос, по внешнему виду это скорее запах кода, чем я думал. спасибо за информацию –

+2

Тестирование на равенство с 'True' не является избыточным (хотя я согласен, что это неразумно). Это может быть вызов '__eq__' или другого специального метода, который мог бы делать практически все. –

+4

@Scott Griffiths: Хорошая точка. Это действительно ужасающий сценарий. Если это на самом деле, программа нарушает наши основные ожидания таким образом, что это делает что-то, что нужно просто удалить и переписать с нуля без такой черной магии. –

3

Я хотел бы подчеркнуть, что, даже если бывают ситуации, когда if expr : не является достаточным, так как один хочет, чтобы убедиться, что expr является True, а не только отличаются от 0/None/все, is должны быть предпочитаемым от ==for the same reason S.Lott mentionned for avoiding == None ,

Это действительно немного более эффективно и, вишня на торте, более читаемая человеком.

Вход:

from time import time 
t0 = time() 
print ((1 == 1) == True) 
t1 = time() 
print ((1 == 1) is True) 
t2 = time() 
print '{:e}s\n{:e}s'.format(t1-t0, t2-t1) 

Выход:

True 
True 
1.201630e-04s 
8.797646e-05s 
Смежные вопросы