Тернарный оператор с исключениями? - PullRequest
3 голосов
/ 24 января 2020

Я часто пишу код, такой как:

try:
    name = names[2]
except IndexError:
    name = names[1]

или, может быть:

try:
    name = Names.first
except AttributeError:
    name = Names.default

Поскольку существует хороший синтаксис для троичных операторов, я задавался вопросом, было ли что-то подобное за исключением? Что-то вроде:

name = names[2] except IndexError names[1]

name = Names.first except AttributeError Names.default

, что соответствует стилю троичного оператора:

name = names[2] if names[2] else names[1]

Ответы [ 2 ]

4 голосов
/ 24 января 2020

Нет выражений для работы с исключениями (хотя есть отклоненный PEP , который пытался ввести одно). Однако во-первых, вы можете избежать исключения.

name = names[2:0:-1][0]  # At the cost of making a small temporary list object

Предполагая, что names имеет как минимум 2 значения, срез создает список, первый элемент которого либо names[2], либо names[1], в зависимости от того, сколько элементов names на самом деле имеет. Какой бы ни был первый элемент среза, извлекается с использованием [0].

Также нет эквивалента dict.get, который позволил бы вам написать что-то вроде names.get(2, names[1]), хотя это предполагает, что, возможно, ваш список должен быть dict или чем-то более структурированным c.

2 голосов
/ 24 января 2020

Этот синтаксис не существует, но вы можете сделать что-то похожее:

Чтобы обработать IndexError, проверьте, находится ли индекс в пределах диапазона:

name = names[2 if 2 in range(len(names)) else 1]

Чтобы обработать AttributeError, используйте getattr со значением по умолчанию:

name = getattr(Names, 'first', Names.default)

Редактировать: Как подсказал @chepner, первое также может быть упрощено до них:

name = names[2 if len(names) > 2 else 1]

name = names[min(len(names), 2)] # if len(names > 0) and you just want the last element.
...