2016-03-19 2 views
1

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

def decorator(func): 
    def _decorator(request, *args, **kwargs): 
     if condition: 
      return func(request, *args, **kwargs) 
     else: 
      """ 
      THIS EXCEPTION CAN'T BE CAUGHT FROM FUNCTION DECORATED 
      """ 
      raise LimitReached 
return _decorator 

Как я могу направиться дальше?

+0

Единственный способ поймать исключение - это блок «try» , Блок 'try' может появляться где угодно в' func() '. Что говорит декоратору, где бросить исключение? – zondo

+1

Если вы имеете в виду, как 'func' поймать исключение, можете ли вы изменить свой вопрос, чтобы объяснить, почему вы разработали свой код таким образом? Невозможно передать исключение _down_ стек вызовов, но, возможно, есть другой способ решить вашу проблему. – snakecharmerb

+2

Вы не можете. Вызов 'func()' уже завершен *. Как это будет работать в любом случае, в какой момент в func() 'должно возникнуть исключение? –

ответ

1

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

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

(2) Декоратор вызывает украшенную функцию ... теперь декоратор не может вызвать исключение, потому что он не работает.

(3) функция возвращается, и код декоратора снова запускается ... украшенная функция не может ничего поймать, потому что ее алеады завершили выполнение.

(редактировать)

Существует решение этой проблемы. func знает, что он должен поймать какое-то исключение. Этот же func можно записать, чтобы иметь параметр, который сообщает ему, что он находится в состоянии ошибки. Я не уверен, что это лучшее решение (нужен даже декоратор?), Но я мог быть уверен ...

def func(p1, p2, kw1=None, errorstate=None): 
    if errorstate: 
     do_error_path() 
     return 

def decorator(func): 
    def _decorator(request, *args, **kwargs): 
     if condition: 
      return func(request, *args, **kwargs) 
     else: 
      kwargs = kwargs.copy() 
      kwargs['errorstate'] = LimitReached() 
      return func(request, *args, **kwargs) 
return _decorator 
Смежные вопросы