Рекомендация: следует ли мне часто использовать обработчики исключений в коде Python или следует избегать, если это возможно? - PullRequest
0 голосов
/ 21 октября 2011

У меня есть проект, где я должен делать это очень часто:

if "something" in dict:
    some_var = dict["something"]
    del dict["something"]
else:
    error_handler_or_other_stuff()

Однако у меня есть идея использовать это:

try:
    some_var = dict.pop("something")
except KeyError:
    error_handler_or_other_stuff()

У меня вопрос: в общем, как "быстро" попробовать - кроме конструкций для обработки исключений? Можно ли использовать его часто, или все же делать это быстрее «вручную». Также иногда у меня возникает ситуация, когда мне нужно преобразовать значение в целое число:

try:
    some_var = int(dict.pop("something"))
except KeyError:
    error_handler_or_other_stuff("no such key")
except ValueError:
    error_handler_or_other_stuff("bad value for key")

Теперь решение с исключениями кажется довольно хорошим, поскольку я могу выполнить обе проверки за один шаг, а также я удалил исходную пару ключ / значение из dict, что является частью проблемы. Так что я могу сказать по крайней мере: это выглядит как элегантное решение. Однако я не уверен, что это быстрее или если у него есть другие недостатки, о которых я должен беспокоиться.

Ответы [ 4 ]

5 голосов
/ 21 октября 2011

Какая конструкция облегчает понимание и сопровождение вашего кода? Выберите это.

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

4 голосов
/ 21 октября 2011

Почему бы не использовать dict.get или dict.pop с параметром default?

3 голосов
/ 22 октября 2011

На такие вопросы о производительности легко ответить, используя модуль timeit :

setup = '''
d = {'a': 1}
k = 'b'
'''

LBYL = '''
if k in d:
    pass
else:
    pass
'''

EAPF = '''
try:
    d[k]
except KeyError:
    pass
'''

from timeit import Timer

print min(Timer(LBYL, setup).repeat(7, 1000000))
print min(Timer(EAPF, setup).repeat(7, 1000000))

Результаты показывают 0.0546 для подхода if / else и 1.3370 для подхода try / кроме. Последний примерно в 25 раз медленнее первого.

При этом, как правило, вы должны использовать все, что выражает самый ясный код.

Sidenote : оба подхода дают разные ответы для подклассов dict , которые определяют пропущенных для возврата значения.

3 голосов
/ 21 октября 2011

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

Ваш пример настолько тривиален, чтодля начала не стоит беспокоиться о скорости.Подобные микрооптимизации стоят больше времени, просто думая о них, чем вы могли бы сэкономить, используя их.

Код, который вы дали, абсолютно хорош, вот для чего есть исключения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...