Классы данных - связывание базовых методов

Я пытаюсь создать класс с двумя методами:

  • Данные запроса (как генератор)

  • Сохранить как json

    @dataclass
    class Data_Query:
        hierarchic: str
        sku: bool
        pred_lenght: int
    
        def query(self, db):
           if (self.hierarchic == 'store' and self.sku == True):
               x = db.aggregate([{...}]);
               self.export_json(x) 
    
        def export_json(self, x, file):
            with open(f'/home/Documents/dataset/{file}', 'w') as fp:
                for i in x:
                    json.dump(i, fp)
                    fp.write('\n')
    

Когда я выполняю метод запроса, выполняются оба метода.

data = Data_Query('store', True, 56)
data.query(db)

Что мне нужно изменить, чтобы вызвать эти методы по отдельности?

Мой ожидаемый результат:

data.query(db).export_json('abc.json')

1 ответ

Решение

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

@dataclass
class Data_Query:
    hierarchic: str
    sku: bool
    pred_lenght: int

    def query(self, db):
       if (self.hierarchic == 'store' and self.sku == True):
           self.x = db.aggregate([{...}]);
           # self.export_json(x) 
       return self

    def export_json(self, file):
        try:
            x = self.x
        except AttributeError:
            return
        
        with open(f'/home/Documents/dataset/{file}', 'w') as fp:
            for i in x:
                json.dump(i, fp)
                fp.write('\n')
        del self.x

Теперь ты можешь писать data.query(db).export_json('abc.json'), а файл JSON будет записан только в том случае, если действительно выполняется запрос.

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

@dataclass
class Data_Query:
    hierarchic: str
    sku: bool
    pred_lenght: int

    def query(self, db):
       if (self.hierarchic == 'store' and self.sku == True):
           return db.aggregate([{...}])

def export_json(self, x, file):
    with open(f'/home/Documents/dataset/{file}', 'w') as fp:
        for i in x:
            json.dump(i, fp)
            fp.write('\n')

result = data.query(db)
if result is not None:
    export_json(result, 'abc.json')

Вы можете возразить: "Конечноexport_jsonотносится к моему классу; это предполагает, чтоx - это итерация объектов, которая определяется query метод ". В этом случае вы можете определить QueryResult класс и сделать export_jsonметод этого класса. потомDataQuery.query возвращает экземпляр QueryResult, и цепочка выглядит менее произвольной: вы экспортируете результат, а не запрос.

# By the way, I am assuming there is more to this class than a query
# method; otherwise, there should probably just be a regular function
# that takes the db, hierarchic, and sku as arguments.
@dataclass
class DataQuery:
    hierarchic: str
    sku: bool
    pred_length: int

    def query(self, db):
        result = None
        if self.hierarchic == 'store' and self.sku:
            result = db.aggregate(...)
        return QueryResult(result)


class QueryResult:
    def __init__(self, result):
        self.result = result

    def export_json(self, file):
        if self.result is None:
            return

        with open(f'/home/Documents/dataset/{file}', 'w') as fp:
           for i in x:
                json.dump(i, fp)
                fp.write('\n')


data.query(db).export_json('abc.json')
Другие вопросы по тегам