Как оптимизировать код python обратного вызова для лучшей читабельности и питонической практики?

#python #optimization

Вопрос:

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

 params = {'freq': 0, 'initialPublication': True,   'initiallySuspended': False, 'callback': None,   'asynchronous': True,   }     

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

 params[callback] = self.callback_test_sub1  subscribe_attrib = 'subscribe_testSub1'  if not self._subscribe(params, subscribe_attrib):  return False  ......    

Что я могу сделать, чтобы улучшить это, или это уже в лучшей форме?

 class Test:    def callback_test_sub1(self, sub1_data):  print('got sub1 data')    def callback_test_sub2(self, sub2_data):  print('got sub2 data')    def notify_test_sub3(self, sub3_data):  print('got sub3 data')    def _subscribe(self, params, subscribe_attribute):  try:  func = getattr(self.external_obj, subscribe_attribute)  err_status = func(**params)  except AttributeError:  print('no such attribute')   except Exception as e:  print(e)    def __init__(self):  params = {'freq': 0, 'initialPublication': True,  'initiallySuspended': False, 'callback': None, 'asynchronous': True}    ### while doing these 3 callbacks, I feel repetitive  params[callback] = self.callback_test_sub1  subscribe_attrib = 'subscribe_testSub1'  if not self._subscribe(params, subscribe_attrib):  return False  params[callback] = self.callback_test_sub2  subscribe_attrib = 'subscribe_testSub2'  if not self._subscribe(params, subscribe_attrib):  return False  params[callback] = self.callback_test_sub2  subscribe_attrib = 'subscribe_testSub3'  if not self._subscribe(params, notify_test_sub3):  return False  ### while doing these 3 callbacks, I feel repetitive end  return True  

Комментарии:

1. Разве это не должно быть params['callback'] , и в третьем повторяющемся блоке () есть опечатка ( callback_test_sub2 )?

Ответ №1:

Если вы не хотите повторять эти небольшие блоки, вы можете составить список, по которому можно выполнить итерацию:

 callbacks = (('subscribe_testSub1', self.callback_test_sub1),   ('subscribe_testSub2', self.callback_test_sub2),   ('subscribe_testSub3', self.callback_test_sub3)) for attribute, callback in callbacks:  params['callback'] = callback  if not self._subscribe(params, attribute)  return False  

Учитывая, что в вашем примере кода уже показано несколько опечаток/ошибок, было бы действительно полезно уменьшить это повторение. Если имена обратного вызова и атрибутов имеют определенный шаблон, вы также можете вычислить их и извлечь с getattr помощью , но код может стать более неясным и не может быть проверен статически.