Что делает этот код, демонстрирующий исключения? - PullRequest
0 голосов
/ 08 марта 2012

Я учусь на книге Python для абсолютных новичков и дошел до главы об исключениях. Объяснения авторов были все более краткими, и с этим фрагментом кода я полностью сбит с толку, и нет никаких объяснений! Может кто-нибудь объяснить, пожалуйста, построчно?

#!/usr/bin/env python
store = []
try: {}["foo"]
except KeyError as e: store.append(e)
try: 1/0
except ZeroDivisionError as e: store.append(e)
try: "".bar()
except AttributeError as e: store.append(e)
for exceptionobject in store:
    ec = exceptionobject.__class__
    print(ec.__name__)
    indent = " +-"
    while ec.__bases__:
        ec = ec.__bases__[0]
        print(indent + ec.__name__)
        indent = " " + indent

Ответы [ 2 ]

4 голосов
/ 08 марта 2012
# create a list
store = [] 

try:
    # if something in this block would throw an exception,
    # code could continue in a controlled way in an except block

    # force a KeyError by looking up a non-existent key in an empty dictionary
    {}["foo"] 

except KeyError as e: 
    # store the exception object in the list
    store.append(e)

# same scheme here; construct something that fails (1/0), 
# then instead of quitting the interpreter, continue operations
try: 
    1/0
except ZeroDivisionError as e: 
    store.append(e)

# pythons exceptions hierarchy is diverse and exceptions carry meaningful
# names expressing their context
try:
    # here we attept to lookup an attribute (that's happening technically
    # before the call), which does not exists (because strings don't know
    # how to bar... 
    "".bar()

except AttributeError as e:
    # ... and the the appropriate exception here is AttributeError
    store.append(e)

На данный момент в списке есть три элемента, которые являются объектами исключений.

# loop over list
for exceptionobject in store:

    # get the class of the object via special method __class__
    # __class__ returns an object whose class is type actually;
    # but don't be too confused by this 
    ec = exceptionobject.__class__

    # print the name of the exception class, now this is just a plain string
    print(ec.__name__)

    indent = " +-"

    # use another special method __bases__ to get all superclasses
    # of the exception class; all exceptions inherit from BaseException
    # loop over the base classes
    while ec.__bases__:

        # get the first base class
        ec = ec.__bases__[0]

        # print its name an indent more
        print(indent + ec.__name__)
        indent = " " + indent

Результат должен выглядеть примерно так:

KeyError
 +-LookupError
  +-StandardError
   +-Exception
    +-BaseException
     +-object
ZeroDivisionError
 +-ArithmeticError
  +-StandardError
   +-Exception
    +-BaseException
     +-object
AttributeError
 +-StandardError
  +-Exception
   +-BaseException
    +-object

с отображением части иерархия исключений .

4 голосов
/ 08 марта 2012

В первой половине (той, которая содержит три предложения except) она вызывает те же самые исключения, которые она ловит (вы ловите исключения с ключевым словом except), затем в обработчике исключений (код сразу после ключевого слова ; запускается при возникновении исключения или повышается ) добавляет каждое исключение в список.

Во второй половине он перебирает сохраненные исключения (те, которые сейчас в списке) и показывает некоторые их атрибуты.

Из этого упражнения вы, вероятно, должны в основном отбирать то, как вы ловите исключения, и только во вторую очередь тот факт, что Исключение является объектом, как и все в Python:

In [6]: KeyError.__class__
Out[6]: type

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

In [7]: err = KeyError()
In [8]: err.__class__
Out[8]: KeyError

Здесь мы создаем экземпляр объекта KeyError, который происходит автоматически при возникновении исключения KeyError (err в этом случае совпадает с e в обработчиках исключений в вашем коде). Как видите, класс err равен KeyError, как и ожидалось.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...