InfoCity
InfoCity - виртуальный город компьютерной документации
Реклама на сайте







Размещение сквозной ссылки

 

Глава 8. Ошибки и исключения


До сих пор сообщения об ошибках только упоминались, но если Вы опробовали приведенные нами примеры, то, вероятно, Вы их видели. Существует (по крайней мере) две различные разновидности ошибок: синтаксические ошибки и исключения.


8.1 Синтаксические ошибки


Синтаксические ошибки, также известные как ошибки разбора, возможно, будут чаще всего возникать пока Вы еще изучаете Python:

>>> while 1 print ‘Привет, мир’
  File "<stdin>", line 1
    while 1 print ‘Привет, мир’
                ^
SyntaxError: invalid syntax
>>>

Разборщик повторяет соответствующую строку и выводит маленькую "стрелку", указывающую на позицию в строке, где была обнаружена ошибка. Ошибка была вызвана словом, предыдущим стрелке: в примере, ошибка обнаружена на ключевом слове print , поскольку перед ним отсутствует двоеточие. Имя файла и номер строки выводятся для того, чтобы Вы знали где искать ошибку.


8.2 Исключения


Даже если оператор или выражение синтаксически корректно, может возникнуть ошибка при попытке их исполнения. Ошибки, обнаруженные во время выполнения, называются исключениями, и не являются безусловно фатальными: Вы скоро научитесь их обрабатывать в Python программах. Однако, большинство исключений программно не обрабатываются, и результат - сообщение об ошибке, как показано ниже:

>>> 10*(1/0)
Traceback (innermost last):
  File "<stdin>", line 1
ZeroDivisionError: integer division or modulo 14 
>>> 4+spam*3
Traceback (innermost last):
  File "<stdin>"", line 1
NameError: spam 15 
>>> ‘2’+2
Traceback (innermost last):
  File "<stdin>", line 1
TypeError: illegal argument type for built-in operation 16 
>>>

Последняя строка сообщения об ошибке дает знать, что случилось. Ошибки возникают различных типов, и тип выводится как часть сообщения: в примере мы увидели типы ZeroDivisionError, NameError и TypeError. Строка, выводимая как тип исключения, является названием встроенного имени возникшего исключения. Это истинно для всех встроенных исключений, но не обязано быть истинным для исключений, определяемых пользователем (хотя это является полезным соглашением). Имена стандартных исключений - это встроенные идентификаторы (а не зарезервированные ключевые слова).

Остаток строки является деталью, толкование которой зависит от типа исключения.

Предыдущая часть сообщения об ошибке показывает контекст, где возникло исключение, в форме обратного прохода стека. Обычно, эта часть содержит список строк обратного прохода стека; однако, строки, прочитанные со стандартного ввода, не будут печататься. Список встроенных исключений и их значения даются в "Справочном руководстве Python" 17 .


8.3 Обработка исключений


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

>>> numbers=[0.3333,2.5,0,10]
>>> for x in numbers:
...     print x,
...     try:
...        print 1.0/x
...     except ZeroDivisionError:
...        print ‘*** не имеет обратного числа ***’
...
0.3333 3.00030003
2.5 0.4
0 *** не имеет обратного числа ***
10 0.1
>>>

Оператор try работает следующим образом.

  • Сперва выполняется пункт try (оператор/ы между ключевыми словами try и except ).
  • Если при этом не возникает исключения, то пункт except пропускается и завершается выполнение оператора try.
  • Если же в процессе выполнения пункта try возникает исключение, то остаток этой секции пропускается. Затем, если тип возникшего исключения встреяается в именах, перечисленных после ключевого слова except , то выполняется пункт except , после чего выполнение продолжается со следующего try оператора.
  • В случае, когда возникает исключение, которого нет среди перечисленных имен в пункте except , оно передается внешнему пункту try ; если обработчик не найден, то это необработанное исключение и выполнение прерывается с сообщением об ошибке, как показано выше.

Оператор try может иметь более одного пункта except , чтобы задать обработчики для различных исключений. Будет выполнено не более одного пункта. Обработчики обрабатывают только исключения, возникающие в соответствующем пункте try , а не в других обработчиках этого же оператора try . Пункт except может именовать несколько исключений, как список, заключенный в скобки:

... except (RuntimeError, TypeError, NameError):
...     pass

Последний пункт except может не указывать имена исключений, в таком случае он будет служить как универсальный обработчик. Однако, используйте этот способ с чрезвычайной осторожностью, поскольку, Вы тем самым маскируете реальные ошибки программирования !

Когда возникает исключение, оно может иметь некоторое ассоциированное значение, также известное как аргумент исключения. Для тех типов исключений, которые имеют аргументы, пункт except может определить переменную после имени исключения (или списка) для получения значения аргумента, как следует ниже:

>>> try:
...    spam()
... except NameError, x:
...    print ‘имя’, x, ‘не определено’
...
имя spam не определено
>>>

Если исключение имеет аргумент, то он выводится как последняя часть ("деталь") сообщения необработанного исключения.

Обработчики исключений обрабатывают не только те, которые возникли непосредственно в секции try , но также и имевшие место внутри функций, вызванных (даже если и косвенно) из пункта try . Например:

>>> def this_fails():
...     x=1/0
...
>>> try:
...     this_fails()
... except ZeroDivisionError, detail:
...     print ‘Обработанная ошибка времени выполнения:’,detail
...
Обработанная ошибка времени выполнения: integer division or modulo
>>>

8.4 Генерация исключений


Оператор raise позволяет программисту заставить возникнуть определенное исключение. Например:

>>> raise NameError, ‘HiThere’
Traceback (innermost last):
  File "<stdin>", line 1
NameError: HiThere
>>>

Первый аргумент raise - имя генерируемого исключения. Необязательный второй параметр определяет аргумент исключения.


8.5 Исключения, определяемые пользователем


Программы могут именовать свои собственные исключения путем присваивания строки некоторой переменной. Например:

>>> my_exc=’мое_исключение’
>>> try:
...     raise my_exc, 2*2
... except my_exc, val:
...     print ‘Возникло мое исключение, значение:’, val
...
Возникло мое исключение, значение: 4
>>> raise my_exc, 1
Traceback (innermost last):
  File "<stdin>", line 1
мое_исключение: 1
>>>

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


8.6 Определение завершающих действии


Оператор try имеет еще один необязательный пункт, который введен для определения завершающих действий, выполняющихся при любых обстоятельствах. Например:

>>> try:
...      raise KeyboardInterrupt
... finally:
...      print ‘Прощай, мир!’
...
Прощай, мир!
Traceback (innermost last):
  File "<stdin>", line 2
KeyboardInterrupt
>>>

Пункт finally выполняется независимо от того, возникло, или нет, исключение в пункте try . Когда возникает исключение, оно генерируется после того, как исполнится секция finally . Пункт finally выполняется также "по пути наружу", когда оператор try покидается по команде break или return .

Оператор try может иметь либо один или более пунктов except , либо пункт finally , но никак не оба одновременно.

[Назад][Содержание][Вперед]


Реклама на InfoCity

Яндекс цитирования



Финансы: форекс для тебя








1999-2009 © InfoCity.kiev.ua