Цепочка методов в python и как получить доступ ко всей строке

Я хотел бы добавить базовый класс, который выполняет некоторую цепочку методов в стиле sql/pandas. Что-то вроде:

ResultSet.filter(...).exclude(...).sort(...)

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

Тем не менее, я также хочу иметь возможность проанализировать всю последовательность цепочки методов, поскольку иногда мне придется делать что-то по-другому, если следующий/предшествующий метод выполняет определенное действие. В общем, я хочу иметь доступ ко всему "ResultSet.filter(...).exclude(...).sort(...)" в виде строки, сохраненной где-то.

Это похоже на то, что мне нужен метод prepare, который хранит строку всего «оператора», а затем фактические методы выполнения filter, exclude и т. д. Возможно, самым простым способом может быть просто добавить метод .execute() или .commit() в конце, который создает контекст, а затем оценивает все.

Как это можно сделать?

Что ты имеешь в виду под "сохранил где-то"? Сохранять в памяти или на диске? Кроме того, нет ничего плохого в вашем подходе к построению контекста в конце. Если бы вы могли упомянуть, зачем вам нужна последовательность цепочек, было бы здорово.

Vishnudev Krishnadas 15.12.2020 05:44

Каждый из методов объекта filter(...), exclude(...), sort(...) и т. д. может добавлять имя своего метода и *args к списку цепочки операций. Это то, что вы имели ввиду?

Jerry101 15.12.2020 05:50

@Vishnudev Я просто имею в виду сохранение в контексте экземпляра. Что-то вроде self.statement_str = "ResultSet.filter(...).exclude(...).sort(...)".

David542 15.12.2020 05:57

@ Jerry101 да, точно.

David542 15.12.2020 05:57

Почему бы вам не создать хранимую процедуру?

Vishnudev Krishnadas 15.12.2020 06:07

@Vishnudev это не имеет ничего общего с вызовами базы данных. Это для чего-то локального для python.

David542 15.12.2020 06:13
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
6
107
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Этот подход регистрирует операции:

class ResultSet:
  def __init__(self):
    self.operation_sequence = []

  def filter(self, *args):
    self.operation_sequence.append(('filter', args))
    ... filter work ...
    return self

  def exclude(self, *args):
    self.operation_sequence.append(('exclude', args))
    ... exclude work ...
    return self

  def sort(self, *args):
    self.operation_sequence.append(('sort', args))
    ... sort work ...
    return self

  @property
  def sequence(self):
    return self.operation_sequence  # reformat the data as desired

Этот подход накапливает отложенные операции до тех пор, пока не будет вызван метод execute():

class ResultSet:
  def __init__(self):
    self.operation_sequence = []

  def filter(self, *args):
    self.operation_sequence.append(('filter', args))
    return self

  def exclude(self, *args):
    self.operation_sequence.append(('exclude', args))
    return self

  def sort(self, *args):
    self.operation_sequence.append(('sort', args))
    return self

  def execute(self):
    ## TODO: Process the interdependencies then run the operations.
    self.operation_sequence = []

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

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

David542 15.12.2020 09:17

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

Jerry101 15.12.2020 09:21

Другие вопросы по теме