Вопрос разработки в Python: это должна быть одна общая функция или две конкретные? - PullRequest
3 голосов
/ 07 сентября 2010

Я создаю базовый служебный класс базы данных в Python. Я рефакторинг старого модуля в класс. Сейчас я работаю над функцией executeQuery(), и я не уверен, сохранить ли старый дизайн или изменить его. Вот 2 варианта:

  1. (старый дизайн :) Имеется один общий метод executeQuery, который принимает запрос на выполнение, и логический параметр commit, который указывает, следует ли фиксировать (вставить, обновить, удалить) или нет (выбрать), и определить с помощью оператор if для принятия или для выбора и возврата.
  2. (Это тот способ, к которому я привык, но это может быть из-за того, что у вас не может быть функции, которая иногда возвращает что-то, а иногда нет в языках, с которыми я работал :) Есть 2 функции, executeQuery и executeUpdateQuery (или что-то эквивалентное). executeQuery выполнит простой запрос и вернет набор результатов, а executeUpdateQuery внесет изменения в БД (вставка, обновление, удаление) и ничего не вернет.

Допустимо ли использовать первый способ? Мне кажется неясным, но, может быть, это более Pythonistic ...? Python очень гибок, может быть, я должен воспользоваться этой возможностью, которая не может быть реализована таким образом на более строгих языках ...

И вторая часть этого вопроса, не связанная с основной идеей - каков наилучший способ возврата результатов запроса в Python? Использование какой функции для запроса базы данных, в каком формате ...?

Ответы [ 3 ]

4 голосов
/ 08 сентября 2010

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

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

2 голосов
/ 08 сентября 2010

У меня есть два метода, один для обновления базы данных, а другой - нет.Оба могут делегировать общий частный метод, если они совместно используют много кода.

Разделив два метода, для вызывающих абонентов становится ясно, какова различная семантика между ними, что упрощает документирование различных методов,и уточняет, какие возвращаемые типы ожидать.Поскольку вы можете извлекать общий код в приватные методы объекта, вам не нужно беспокоиться о дублировании кода.

Что касается возврата результатов запроса, то это будет зависеть от того, загружаете ли вы все результаты из базы данных до этого.возврат или возврат объекта курсора.Я бы хотел сделать что-то вроде следующего:

with db.executeQuery('SELECT * FROM my_table') as results:
    for row in results:
        print row['col1'], row['col2']

... поэтому метод executeQuery возвращает объект ContextManager (который очищает все открытые соединения, если это необходимо), который такжедействует как Generator.И результаты от генератора действуют только для чтения dict s.

2 голосов
/ 07 сентября 2010

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

Когда вы собираетесь вернуть последовательность неопределенной длины, лучше всего использовать генератор .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...