У меня есть функция, которая может возвращать одно из трех:
- успех (
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
части, или я должен добавить тип данных tri-bool. Я не хочу, чтобы simulate
функция генерировала исключение, поскольку все, что я хочу, чтобы внешняя программа делала с ошибкой, - это регистрировать ее и продолжать.
simulate
функции я ловлю все исключения; Я не хочу, чтобы что-либо, происходящее внутри симулятора, останавливало выполнение остальной части программы (и обработку следующего элемента). Но ответы заставляют меня изменить свое мнение.simulate
есть что-то, что он может поймать и повторить, это хорошо. Но если он «проваливается», он не должен возвращатьсяNone
. Он должен просто вызвать исключение для сценария, который его вызвал. В любом случаеsimulate
готово. ВозвратNone
не так полезен, как создание правильного исключения - или разрешение исключения распространятьсяsimulate
в вызывающий скрипт для обработки.except Exception:
вместо этого. Это перехватывает все "настоящие" ошибки вместе сWarning
иStopIteration
. Это позволяетKeyboardInterrupt
иSystemExit
насквозь. Если вы действительно хотите их поймать, вероятно, лучше всего использовать другую, внешнюю try / except или какую-то другую структуру, которая четко документирует ваше намерение, поскольку это не «ошибки». (Но я сказал «почти никогда» ... возможно, в вашем случае вы действительно хотите захватить все и даже предотвратить Ctrl-C илиsys.exit()
выход и т. Д.)Ответы:
Не бойтесь исключения! Заставить вашу программу просто войти и продолжить - это так же просто, как:
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
И теперь у вас может быть гораздо более богатый тип уведомления от метода моделирования о том, что именно пошло не так, если вы обнаружите, что ошибка / отсутствие ошибки недостаточно информативны.
источник
traceback.format_exc()
. См. Этот ТАК ответ.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.источник
Никогда, никогда, никогда не говори
if something == True:
Никогда. Это безумие, поскольку вы повторно повторяете то, что избыточно указано как правило избыточного условия для оператора if.
Хуже того, никогда, никогда, никогда не говори
if something == False:
У тебя есть
not
. Не стесняйтесь использовать это.Наконец, делать
a == None
это неэффективно. Делайa is None
.None
это особый одноэлементный объект, может быть только один. Просто проверьте, есть ли у вас этот объект.источник
True
не является избыточной (хотя я согласен, что это нецелесообразно). Это может быть вызов какого-__eq__
либо специального метода, который может делать практически все.if something == True
когда результат отличается отif something
, например, для небулеваsomething
.2==True
дает ложь, тогда как2
оценивается как истина;None==False
ложно, ноnot None
верно!something
возвращенияTrue
наbool(something)
. В этом случае, если вы хотите ТОЛЬКО проверить,something
имеет ли значениеTrue
iebool
. Тогда вы ДОЛЖНЫ сделатьif something == True
ИМО.Я хотел бы подчеркнуть, что, даже если есть ситуации, когда
if expr :
этого недостаточно, потому что нужно убедиться, что онexpr
есть,True
а не просто отличается от0
/None
/ чего-то еще,is
следует предпочесть==
по той же причине, по которой С.Лотт упомянул, что он избегает== None
.Это действительно немного более эффективно и, главное, удобочитаемо.
In [1]: %timeit (1 == 1) == True 38.1 ns ± 0.116 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) In [2]: %timeit (1 == 1) is True 33.7 ns ± 0.141 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
источник
Есть много хороших ответов. Хочу добавить еще один момент. Ошибка может попасть в ваш код, если вы работаете с числовыми значениями, и ваш ответ оказался 0.
a = 0 b = 10 c = None ### Common approach that can cause a problem if not a: print(f"Answer is not found. Answer is {str(a)}.") else: print(f"Answer is: {str(a)}.") if not b: print(f"Answer is not found. Answer is {str(b)}.") else: print(f"Answer is: {str(b)}") if not c: print(f"Answer is not found. Answer is {str(c)}.") else: print(f"Answer is: {str(c)}.")
Answer is not found. Answer is 0. Answer is: 10. Answer is not found. Answer is None.
### Safer approach if a is None: print(f"Answer is not found. Answer is {str(a)}.") else: print(f"Answer is: {str(a)}.") if b is None: print(f"Answer is not found. Answer is {str(b)}.") else: print(f"Answer is: {str(b)}.") if c is None: print(f"Answer is not found. Answer is {str(c)}.") else: print(f"Answer is: {str(c)}.")
Answer is: 0. Answer is: 10. Answer is not found. Answer is None.
источник
Я считаю, что создание исключения - лучшая идея для вашей ситуации. Альтернативой будет метод моделирования для возврата кортежа. Первый элемент будет статусом, а второй - результатом:
result = simulate(open("myfile")) if not result[0]: print "error parsing stream" else: ret= result[1]
источник
False
будет возвращен, он напечатает'error parsing stream'
.