пользовательские исключения в Python, похоже, не следуют "легче просить прощения"? - PullRequest
2 голосов
/ 19 апреля 2020

Я пытаюсь улучшить свое кодирование и недавно натолкнулся на пользовательские исключения и концепцию «Проще просить прощения, чем разрешения» (EAFP), но мне не кажется, что пользовательские исключения все еще следуют этой концепции.

Например, в приведенном ниже коде A выглядит чисто, но не является пользовательским исключением. B также выглядит чисто, но не является пользовательским исключением и не соответствует концепции EAFP. Альтернативой B является замена KeyError пользовательской ошибкой. C имеет пользовательское исключение, но оно кажется довольно многословным, и для меня оно почти похоже на LBYL.

Является ли пример C типичным образом, как используются пользовательские исключения? (с помощью try / кроме AND, если / else)

Стоит ли использовать дополнительные строки кода в примере C для кода промышленного уровня, который будут использовать многие люди?

animal_dict={'cat':'mammal', 
             'dog':'mammal', 
             'lizard':'reptile'}

# A - easier to ask for forgiveness not permission (EAFP)
try:
    animal_type = animal_dict['hamster']
except KeyError:
    print('Your animal cannot be found')


#B - look before you leap (LBYL)
if 'hamster' in animal_dict:
    animal_type = animal_dict['hamster']
else:
    raise KeyError('Your animal cannot be found')


# C - with custom exception
class AnimalNotFoundError(KeyError):
    pass

try:
    if 'hamster' in animal_dict:
        animal_type = animal_dict['hamster']
    else:
        raise AnimalNotFoundError('Invalid animal: {}'.format('hamster'))
except AnimalNotFoundError as e:
    print(e)

1 Ответ

4 голосов
/ 19 апреля 2020

В этом случае вы должны использовать свое пользовательское исключение, чтобы добавить детали к исключению generi c KeyError. Вы можете использовать ключевое слово from в блоке обработки исключений, чтобы связать ваше исключение с базовым исключением, например:

class AnimalNotFoundError(KeyError):
    pass

try:
    # Don't look, just take
    animal_type = animal_dict['hamster']
except KeyError as ex:
    # Add some detail for the error here, and don't silently consume the error
    raise AnimalNotFoundError('Invalid animal: {}'.format('hamster')) from ex
...