2013-11-15 2 views
3

У меня следующий код для обработчика щелчка в моей программе PyQt4:Объявляет функцию внутри функции для пронизывания хорошего стиля программирования?

def click_btn_get_info(self): 
    task = self.window.le_task.text() 
    self.statusBar().showMessage('Getting task info...') 

    def thread_routine(task_id): 
     order = self.ae.get_task_info(task_id) 
     if order: 
      info_str = "Customer: {email}\nTitle: {title}".format(**order) 
      self.window.lbl_order_info.setText(info_str) 
      self.statusBar().showMessage('Done') 
     else: 
      self.statusBar().showMessage('Authentication: failed!') 

    thread = threading.Thread(target=thread_routine, args=(task,)) 
    thread.start() 

Это хорошая практика, чтобы объявить функцию в функции для использования с потоками?

+6

Я не уверен, используя threading.Thread с классом PyQt4 является хорошей практикой. Существуют альтернативы с потоком, поставляемые с PyQt4. –

+3

@Hyperboreus: Это неправда, и это очень опасный совет. Существует всего один цикл событий с одной очередью событий, который передает сигналы в 'QObjects', вызывая их метод' event'. Если вы делаете что-то медленное или блокируемое обработчиком 'event' на одном объекте, вы блокируете весь поток. См. [Темы, События и QObjects] (http://qt-project.org/wiki/ThreadsEventsQObjects) для лучшего объяснения. – abarnert

+1

@abarnert Спасибо, abarnert. Я удалил свой комментарий. Я был явно ошибаюсь. – Hyperboreus

ответ

5

В целом, да, это вполне разумно. Однако альтернативой создания отдельного метода (или для кода верхнего уровня, отдельной функции) является также совершенно разумно. И поэтому создается подкласс Thread. Итак, нет правила, говорящего всегда делать один из трех; есть разные случаи, когда каждый из них кажется более разумным, чем другие, но между этими случаями существует совпадение, поэтому обычно это решение.

Как указал Максим, вы, вероятно, захотите использовать Threading Qt, а не нативную начинку Python. Тем более, что вы хотите вызывать методы для объектов GUI. В статье Qt docs статьи Threads, Events and QObjects в документации Qt представлен обзор (хотя с точки зрения C++, а не Python, viewpoint). И если вы используете QThread, а не threading.Thread, гораздо чаще используется метод OO - определить подкласс QThread и переопределить его метод run, чем определить функцию, что делает ваш вопрос спорным.

Но если вы придерживаетесь нити Python, вот как я решил.

Pro отдельный метод:

  • Вы делаете это в методе класса, а не функции, а также о том, что только государство вы хотите поделиться с новой нити self.
  • Нетривиального код, больше, чем функции она встроена в

Pro локальной функция:.

  • Довольно специфично для кнопки обратного вызова информации; никто другой никогда не захочет назвать это.

Я бы предположил, что это метод, но я бы не стал жаловаться на чужой код, который сделал его локальной функцией.

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

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