Если вы обнаружите, что пишете много повторяющегося кода Python, это отличное упражнение для объединения с открытыми функциями.

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

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

Повторяющийся код может вызвать путаницу

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

Взгляните на этот пример. Первая функция обновляет название статьи, а вторая обновляет описание. Заметили что-нибудь другое? Нет, за исключением самого поля.

def update_article_name(article_id, new_article_name):
     u = update(table).where(table.c.articleID == article_id)
     u = u.values(name=new_article_name)
     result = connection.execute(u)
     print(result.rowcount)
def update_article_description(article_id, new_description):
     u = update(table).where(table.c.articleID == article_id)
     u = u.values(description=new_description)
     result = connection.execute(u)
     print(result.rowcount)

Не нужно тратить место на написание кода

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

def update_article(article_id, new_value, update_type=None):
     u = update(dal.table).where(dal.table.c.articleID== article_id)
     if update_type == None:
          raise Exception('Update type not specified')
     elif update_type == 'name':
          u = u.values(name=new_value)
     elif update_type == 'description':
          u = u.values(description=new_value)
     elif update_type == 'author':
          u = u.values(author=new_value)
     elif update_type == 'publication':
          u = u.values(publication = new_value)
     elif update_type == 'category_id':
          u = u.values(categoryID=new_value)
     elif update_type == 'date':
          u = u.values(date=new_value)
     else:
          print('Invalid update type')
          return
     result = dal.connection.execute(u)
     print(result.rowcount)

Я заменил все функции, обновляющие статьи и категории, одной командой, которая обновляет все на стороне базы данных. Параметр update_type определяет тип обновления. Тогда каждый вид обновления имеет условный оператор if. Самое замечательное в этой функции то, что она поддерживает одновременное обновление нескольких полей.

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

Вы можете узнать больше о генераторе новостей Python здесь