Могу ли я получить локальные переменные функции Python, из которой было сгенерировано исключение? - PullRequest
21 голосов
/ 30 января 2012

Я пишу собственную систему регистрации для проекта. Если функция выдает исключение, я хочу записать свои локальные переменные. Можно ли получить доступ к локальным переменным функции повышения из блока исключений, который перехватил исключение? Например:

def myfunction():
    v1 = get_a_value()
    raise Exception()

try:
    myfunction()
except:
    # can I access v1 from here?

Ответы [ 5 ]

29 голосов
/ 30 января 2012

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

def myfunction():
    v1 = get_a_value()
    raise Exception()

try:
    myfunction()
except:
    # can I access v1 from here?
    v1 = inspect.trace()[-1][0].f_locals['v1']

Функциональность функции trace и формат объектов traceback, с которыми она имеет дело, описаны в документации модуля inspect .

2 голосов
/ 30 января 2012

Вы можете искать локальные переменные в объекте frame, который вы можете получить из sys.exc_info.

>>> import sys
>>> def f(a):
...     b = a - 1
...     print 1.0 / b
...
>>> try:
...     f(1)
... except Exception, e:
...     print sys.exc_info()[2].tb_next.tb_frame.f_locals
...
{'a': 1, 'b': 0}

Вам нужно будет включить соответствующее количество tb_next с в зависимости от того, как глубоко в стеке было сгенерировано исключение.

2 голосов
/ 30 января 2012
def myFunction()
    v1 = get_a_value()
    raise Exception(v1)


try:
    myFunction()
except Exception, e:
    v1 = e.args[0]
1 голос
/ 30 января 2012

Да, если это ваш собственный тип исключения.Как это:

>>> class MyExn(Exception):
...     def __init__(self, val):
...             self.val = val
...     def __str__(self):
...             print "something wrong with:", str(self.val)
... 
>>> def foo():
...     val = 42
...     raise MyExn(val)
... 
>>> foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in foo
__main__.MyExnsomething wrong with: 42

>>> # Or in a try block:
>>> try:
...     foo()
... except MyExn as e:
...     print e.val
... 
42
>>> 
0 голосов
/ 30 января 2012
try:
    myfunction()
except:
    import sys
    type, value, tb = sys.exc_info()
    while tb.tb_next:
        tb = tb.tb_next
    frame = tb.tb_frame
    print frame.f_locals['v1']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...