Да, вы можете (для простых случаев), но вам нужно немного метапрограммирования. Как и в других ответах, функция не объявляет, что выдает конкретный тип ошибки, поэтому вам нужно посмотреть на модуль и посмотреть, какие типы исключений он определяет, или какие типы исключений он вызывает. Вы можете попытаться получить документацию или использовать Python API для этого.
Чтобы сначала найти, какие типы исключений определяет модуль, просто напишите простой скрипт, который просматривает каждый объект в словаре модуля module.__dict__
и посмотрите, заканчивается ли он словом «Ошибка» или является подклассом исключения:
def listexns(mod):
"""Saved as: http://gist.github.com/402861
"""
module = __import__(mod)
exns = []
for name in module.__dict__:
if (issubclass(module.__dict__[name], Exception) or
name.endswith('Error')):
exns.append(name)
for name in exns:
print '%s.%s is an exception type' % (str(mod), name)
return
Если я запускаю это на вашем примере shutils
, я получаю это:
$ python listexn.py shutil
Looking for exception types in module: shutil
shutil.Error is an exception type
shutil.WindowsError is an exception type
$
Это говорит о том, какие типы ошибок определены, а какие нет. Чтобы достигнуть последнего, нам нужно пройтись по абстрактному синтаксическому дереву, сгенерированному, когда интерпретатор Python анализирует модуль, и искать каждый оператор raise
, а затем сохранять список имен, которые возникают. Код для этого немного длинный, поэтому сначала я изложу вывод:
$ python listexn-raised.py /usr/lib/python2.6/shutil.py
Looking for exception types in: /usr/lib/python2.6/shutil.py
/usr/lib/python2.6/shutil.py:OSError is an exception type
/usr/lib/python2.6/shutil.py:Error is an exception type
$
Итак, теперь мы знаем, что shutil.py
определяет типы ошибок Error
и WindowsError
и вызывает типы исключений OSError
и Error
. Если мы хотим быть немного более полными, мы могли бы написать другой метод для проверки каждого предложения except
, чтобы также увидеть, какие исключения shutil
обрабатывает.
Вот код для обхода AST, он просто использует интерфейс compiler.visitor
для создания устройства, которое реализует «шаблон посетителя» из книги «Банды четырех»:
class ExceptionFinder(visitor.ASTVisitor):
"""List all exceptions raised by a module.
Saved as: http://gist.github.com/402869
"""
def __init__(self, filename):
visitor.ASTVisitor.__init__(self)
self.filename = filename
self.exns = set()
return
def __visitName(self, node):
"""Should not be called by generic visit, otherwise every name
will be reported as an exception type.
"""
self.exns.add(node.name)
return
def __visitCallFunc(self, node):
"""Should not be called by generic visit, otherwise every name
will be reported as an exception type.
"""
self.__visitName(node.node)
return
def visitRaise(self, node):
"""Visit a raise statement.
Cheat the default dispatcher.
"""
if issubclass(node.expr1, compiler.ast.Name):
self.__visitName(node.expr1)
elif isinstance(node.expr1, compiler.ast.CallFunc):
self.__visitCallFunc(node.expr1)
return