Ответ 1
Потому что окончание генератора не является общим событием (я знаю, что это всегда произойдет, но это произойдет только один раз). Выбрасывание исключения считается дорогостоящим. Если событие преуспеет в 99% случаев и сработает 1%, использование try/except может быть намного быстрее, чем проверка того, можно ли получить доступ к этим данным (проще попросить прощения, чем разрешение).
Там также есть смещение против него, поскольку try/except используемые таким образом блоки могут быть очень трудными для понимания. Контроль потока может быть затруднен, в то время как if/else более прост. Функция try/except означает, что вы должны отслеживать управление потоком операторов внутри try и внутри функций, которые он вызывает (поскольку они могут генерировать исключение и могут распространяться вверх). If/else может только веткиться в точке, когда утверждение.
Бывают случаи, когда использование try/except правильное и время, когда if/else имеет больше смысла. Также есть затраты на производительность, связанные с каждым из них. Рассмотрим:
a = <some dictionary>
if key in a:
print a[key]
против.
a = <some dictionary>
try:
print a[key]
except KeyError:
pass
Первый будет быстрее, если ключ не существует внутри a и будет только немного (почти незаметным) медленнее, если он существует. Второй будет быстрее, если ключ существует, но будет намного медленнее, если он не существует. Если ключ почти всегда существует, вы идете со вторым. В противном случае первое работает лучше.
РЕДАКТИРОВАТЬ: Просто немного, чтобы добавить о попытке Python/кроме того, что очень помогает в решении одной из проблем чтения.
Рассмотрите возможность чтения из файла.
f = None
try:
f = open(filename, 'r')
... do stuff to the file ...
except (IOError, OSError):
# I can never remember which one of these Python throws...
... handle exception ...
finally:
if f:
f.close()
Теперь что-нибудь в do stuff to the file
может выдать исключение, и мы его поймаем. Как правило, вы пытаетесь сохранить как можно меньше кода в попытке по этой причине. Python имеет необязательное предложение else
для try, которое будет запускаться только в том случае, если попытка завершилась до завершения без исключения.
f = None
try:
f = open(filename, 'r')
except (IOError, OSError):
pass
else:
... do stuff to the file ...
finally:
if f:
f.close()
В этом случае у вас не было бы проблем с читабельностью, поскольку в попытке только один оператор; это вызов функции стандартной библиотеки python, и вы обнаруживаете только определенные исключения.