Шаблон проектирования исключений для более описательных исключений

Что такое хороший способ добавить дополнительную информацию в исключение Python

Например, у меня есть вложенные словари

d = {'Bob':{'lastname':'Smith'}, 'Sally':{}}

если я получу доступ к этому словарю, я получаю то, что хочу, это фамилия

name = 'Bob'
value = 'lastname'
print(d[name][value])

кузнец

Если я попытаюсь получить доступ к фамилии Салли, я также получу то, что хочу, это KeyError

name = 'Sally'
value = 'lastname'
print(d[name][value])

KeyError: 'lastname'

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

try:
   name = 'Sally'
   value = 'lastname'
   print(d[name][value])
except KeyError:
   raise KeyError("{0} has no {1}".format(name, value)) 

KeyError: у Салли нет последнего имени

Это дает мне описательную ошибку, которую я ищу, но мне осталось интересно, является ли эта реализация питоновой. Есть ли лучший способ выразить это? Я пробовал просматривать документацию на python и другие распространенные пакеты, но не нашел ничего убедительного, что, по крайней мере, я мог видеть

+2
источник поделиться
1 ответ

Позвольте просто выложить его там и посмотреть, что это заставляет нас. Но сначала рассмотрим статью Джеффа Кнуппа на эту тему. Это может быть обзор, но там есть большие маленькие самородки.

Рассмотрим подход LBYL (посмотрите, прежде чем прыгать - см. Статью):

if name not in d:
    raise KeyError('{0} is not in first level of dict'.format(name))

if value not in d[name]:
    raise KeyError('{0} is not in second level of {1}-dict'.format(value, name))

по сравнению с EAFP (проще просить прощения, чем разрешение - снова см. статью):

try: 
    lastnames = d[name]
except KeyError:
    raise KeyError('{0} is not in the first level of dict'.format(name))

try:
    person = lastnames[value]
except KeyError:
    raise KeyError('{0} is not in the second level of {1}-dict'.format(value, name))

Теперь рассмотрим Дзен Питона. На мой взгляд, прежний подход является более "красивым" и "более простым". Это также поражает меня как "удобочитаемое", хотя и с небольшим отрывом для этого случая. С другой стороны, последний более "явный" в том, что он четко указывает на возможность неудачи и как справиться с такими случаями. Кроме того, если вам когда-либо понадобится расширять деятельность вокруг обработки ошибок, нельзя "игнорировать" "практичность" подхода EAFP; если вам это нужно, сила и удобство полной try: except: else: finally не следует недооценивать. Сказав это, я лично стремлюсь к вашей try: except: решение.

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

Не обращай на меня внимания. Это мнение, в конце концов.

+1
источник

Посмотрите другие вопросы по метке или Задайте вопрос