2016-10-21 3 views
0

Проблема:Изящно ручки подавленные (необработанные) исключения в PyQt4

Я пытаюсь выяснить, лучший метод для обработки необработанного исключения, которые обычно получают подавленные PyQt.

Моего решения прямо сейчас, чтобы украсить соответствующие методы со следующим декоратором

def handleExceptions(func): 
    """ 
    Decorator: create and show message box for every unhandled exception that 
    reaches the decorator 
    """ 
    @functools.wraps(func) 
    def decorator(self): 
     try: 
      func(self) 
     except Exception as error: 

      # ... 

      if errBox.exec_() == QMessageBox.Ok: 
       try: 
        self.closeApp() 
       except AttributeError: 
        exit() 

    return decorator 

Однако это решение работает только тогда, когда ни один из украшенных методов не требуется больше параметров, чем self. Я пытался расширить декоратора, как этот

... 
def decorator(self, *args) 
    try: 
     func(self, *args) 
... 

Это позволяет вызывать функции с одним или несколькими параметрами (в том числе self). К сожалению, этот код нарушает доступ к методам, для которых нет параметров, кроме self, которые выходят из строя с сообщением TypeError: method() takes 1 positional argument but 2 were given.

После использования отладчика я выяснил, что второй параметр в *args выглядит как bool (False).

Вопросы:

  1. Почему этот дополнительный параметр получить прошло?
  2. Каким образом декоратор может быть изменен для использования с функциями переменной длины параметров?
  3. Это даже хороший способ справиться с исключениями? Я был бы признателен, если бы кто-нибудь мог сказать мне обычный метод обработки необработанных исключений в PyQt.

Я посмотрел другие решения, как this one (который я не полностью understant) и пытался реализовать их без успеха (он либо выбрасывает исключения, как мой один или полностью ломает декорированные методы).

Заранее благодарен!

+0

Декоратор кажется ужасно сложным и сложным в обслуживании. [Другой ответ] (http://www.riverbankcomputing.com/news) в вопросе, который вы связали, предлагает использовать [excepthook] (http://docs.python.org/3/library/sys.html#sys .excepthook). Я не знаю, почему кто-то мог бы использовать что-либо еще, учитывая, насколько просто реализовать. – ekhumoro

ответ

1

Хотя я согласен с комментарием, что excepthook, вероятно, путь, вот что-то подобное я сделал сразу:

def handle_exception_decorator(exceptions_to_catch = (ValueError, IndexError, TypeError), return_on_fail=False): 
    def wrap(fn): 
     @functools.wraps(fn) 
     def f(*args, **kwargs): 
      try: 
       return fn(*args, **kwargs) 
      except tuple(exceptions_to_catch) as e: 
       # handle the exception here: 
       return return_on_fail 
     return f 
    return wrap 

Украсьте свои методы с:

@handle_exception_decorator 

или

@handle_exception_decorator(exceptions_to_catch=(AnExceptionType,)) 

или

@handle_exception_decorator(exceptions_to_catch=(Exception,), return_on_fail=7)  

и т.д ...

EDIT: О, на самом деле я думаю, что ваш вопрос, потому что метод вы украшаете слот подключен к сигналу, и ваш слот игнорирует один из аргументов сигнал излучает. Единственный способ исправить это - обновить украшенную функцию, чтобы принять необязательный аргумент ключевого слова, который принимает параметр, испускаемый сигналом. Вы, конечно, не должны использовать его в своем методе, вам просто нужна подпись метода для соответствия тому, что будет излучать сигнал (Qt обычно изящно обрабатывает это, но декораторы, как этот беспорядок, что!)

Смежные вопросы