Python, использующий исключения для потока управления, считается плохим? - PullRequest
19 голосов
/ 01 сентября 2011

Хорошо,

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

Если это так плохо для всех, кто использует python, почемуязык включает его в то, что считается фундаментальной структурой управленияДля тех, кто хочет прочитать соответствующий PEP , перейдите сюда .

Ответы [ 3 ]

13 голосов
/ 01 сентября 2011

Поскольку завершение генератора не является обычным явлением (я знаю, что это всегда будет происходить, но это происходит только один раз ).Бросок исключения считается дорогим.Если событие будет успешным в 99% случаев, а в случае неудачи - 1%, использование попытки / кроме может быть намного быстрее, чем проверка, можно ли получить доступ к этим данным (проще просить прощения, чем разрешения).

Существует также предвзятость, так как блоки try / Кроме таких блоков могут быть очень трудно понять.Управление потоком может быть затруднено, в то время как if / else более просты.Попытка / исключение означает, что вы должны отслеживать управление потоком операторов внутри операторов try и внутри вызываемых им функций (поскольку они могут генерировать исключение и могут распространяться вверх. Оператор if / else может тольковетвление в точке, когда выполняется оценка оператора.

Бывают случаи, когда использование try / exception корректно, и случаи, когда если / else имеет больше смысла. С каждым из них также связаны затраты производительности. Рассмотрим:

a = <some dictionary>
if key in a:
    print a[key]

против

a = <some dictionary>
try:
    print a[key]
except KeyError:
    pass

Первый будет быстрее, если ключ не существует внутри, и будет лишь немного (почти незаметным) медленнее, если он существует.будет быстрее, если ключ существует, но будет намного медленнее, если он не существует. Если ключ почти всегда существует, вы идете со вторым. В противном случае первый работает лучше.

РЕДАКТИРОВАТЬ: Просто немногокое-что добавить о 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 для попытки, которая будет выполняться только в том случае, если попытка завершилась без выполнения исключения.

f = None
try:
    f = open(filename, 'r')
except (IOError, OSError):
    pass
else:
    ... do stuff to the file ...
finally:
    if f:
        f.close()

В этом случае у вас не возникнет проблем с читаемостью, посколькутолько одно утверждение в попытке;это вызов стандартной библиотеки Python, и вы ловите только определенные исключения.

2 голосов
/ 01 сентября 2011

Постоянное использование блоков try для управления потоком может привести к созданию кода, подобного следующему:

try:
  # stuff
  try:
    if userCondition:
      throw NeedToDoSomethingElseException
    try:
      # stuff
    except NeedToDoSomethingElseException:
      # other stuff
  except NeedToDoSomethingElseException:
    # other stuff
except NeedToDoSomethingElseException:
  # other stuff

За исключением проблем производительности, это не очень элегантно.Поэтому иногда вполне уместно использовать try, но не для всего.

1 голос
/ 01 сентября 2011

Поскольку исключения поднимаются в стеке, они подходят для некоторых случаев, когда вы хотите, чтобы код, использующий другой код, мог перехватить исключение.Например, рассмотрим случай, когда вы хотите создать итератор, который использует часть другого итератора более «вручную», важно иметь исключение, которое вы можете отловить из стека выше, и вставить свою собственную логику.

...