Я понимаю, что уже были дискуссии о том, использовать ли блоки If/Else или Try/Except. Такой вопрос находится здесь: Лучше "попробовать" что-то и поймать исключение или сначала проверить, возможно ли это, чтобы избежать исключения?
Но я хотел бы немного расширить обсуждение до вложенных try/except
и вложенных if/elif/else
логических блоков. Вот настройка... Я хочу написать функцию, которая позволит пользователям предоставлять строковый литерал, целое число или итерацию. Это функция высокого уровня, которая обеспечит некоторый уровень абстракции для других функций, которые я написал. Мой код такой:
def high_level_func(parameter = None):
"""
:param parameter: Can accept the string 'All', a single integer, or an iterable such
as a range or a list or tuple of ints.
"""
try:
if parameter.lower() == 'all'
# .lower because str input should be case-insensitive
return str_all_function(parameter) # Only accepts the
# string 'all' - case insensitive
except AttributeError:
# if parameter is an int or iter end up here because those types
# don't have .lower() methods
try:
for para in parameter:
try:
print(int_input_function(parameter))
except MyException:
raise MyException('An iter of something other than ints was '
'provided and cause this error.')
except TypeError:
# parameter must be an int because ints aren't iterable and end up here
return int_input_function(parameter)
В этом случае предположим, что я понятия не имею, какой тип ввода предпочтет большинство пользователей (т. е. равновероятно, что любой данный пользователь передаст либо int
, либо iter
, либо строку «все». Но мы можем с уверенностью предположить, что пользователь, скорее всего, никогда не передаст список строк или кортеж строк - недопустимые iter
s)
Можно ли это сделать, или мне лучше проверить тип ввода и выполнить блок кода if/elif/else (IEE)? По вашему мнению, кодовый блок IEE будет значительно легче читать?
Альтернативное предложение: как насчет использования комбинации try/except и IEE? Команда try/except может попытаться уменьшить ввод, если это, например, строковый литерал 'all', а IEE будет вложен в блок except
для проверки альтернативных случаев (целое число, итерация или недопустимый тип)
И вообще, как я могу определить, какой метод самый быстрый, не написав функцию три раза и не протестировав каждый раз?
Еще один вопрос: если Try/Except в среднем быстрее, чем тест If/Elif/Else, но мы думаем, что If/Elif/Else имеет лучшую читаемость, насколько быстрее должен быть метод Try/Except, чтобы гарантировать читабельность броска в окно или читабельность всегда превалирует перед скоростью? Или это на усмотрение кодера/команды?