Как уменьшить дублирование уровней вложенного словаря при сериализации объекта python - PullRequest
2 голосов
/ 14 февраля 2020

Ниже приведен пример сценария python, где у объекта Market есть объект Fruit, который содержит словарь объектов различного типа. При сериализации рыночного объекта, как показано ниже,

import json

class Fruit:
    def __init__(self, name, color):
        self.name = name
        self.color = color

    def __str__(self):
        return f"name:{self.name}, color:{self.color} \n"

    def as_dict(self):
        return self

class Fruits:
    def __init__(self):
        self.fruits = {}

    def add(self, name, color):
        fruit = Fruit(name, color)
        self.fruits[fruit.name] = fruit

    def __str__(self):
        text = ["Fruits: \n"]
        for exp_id in self.fruits:
            text.append(str(self.fruits[exp_id]))
        sep = ""
        return sep.join(text)

    def as_dict(self):
        return self.fruits

class Market:
    def __init__(self, name):
        self.name = name
        self.fruits = Fruits()

    def __str__(self):
        return f"Market name: {self.name}, \n Fruits: {str(self.fruits)}"

    def as_dict(self):
        return self

m= Market("Grocery market")
m.fruits.add("apple", "red")
m.fruits.add("banana", "yellow")
m.fruits.add("mango", "green")
js = (lambda x: x.__dict__)(m)
s = json.dumps(js, default=lambda x: x.__dict__)

print(s)

вывод json выглядит как:

{
  "name": "Grocery market",
  "fruits": {
    "fruits": {
      "apple": { "name": "apple", "color": "red" },
      "banana": { "name": "banana", "color": "yellow" },
      "mango": { "name": "mango", "color": "green" }
    }
  }
}

Я пытаюсь уменьшить уровень 2 Фруктов до 1, как показано ниже:

{
  "name": "Grocery market",
  "fruits": {
    "apple": { "name": "apple", "color": "red" },
    "banana": { "name": "banana", "color": "yellow" },
    "mango": { "name": "mango", "color": "green" }
  }
}

Мне нужна помощь в понимании того, что было бы лучшим способом go об этом? Я попытался перегрузить dict для класса фруктов, но понял, что его нельзя перегружать.

Любая помощь приветствуется.

Ответы [ 2 ]

1 голос
/ 14 февраля 2020

Попытайтесь быть более явным и избегайте слишком большого количества магов c. Метод to_dict () должен возвращать dict, а не сам объект. Нечто подобное работает нормально.

import json

class Fruit:
    def __init__(self, name, color):
        self.name = name
        self.color = color

    def __str__(self):
        return f"name:{self.name}, color:{self.color} \n"

    def as_dict(self):
        return {
            'name': self.name,
            'color': self.color,
        }

class Fruits:
    def __init__(self):
        self.fruits = {}

    def add(self, name, color):
        fruit = Fruit(name, color)
        self.fruits[fruit.name] = fruit

    def __str__(self):
        text = ["Fruits: \n"]
        for exp_id in self.fruits:
            text.append(str(self.fruits[exp_id]))
        sep = ""
        return sep.join(text)

    def as_dict(self):
        return {k: v.as_dict() for k, v in self.fruits.items()}

class Market:
    def __init__(self, name):
        self.name = name
        self.fruits = Fruits()

    def __str__(self):
        return f"Market name: {self.name}, \n Fruits: {str(self.fruits)}"

    def as_dict(self):
        return {
            'name': self.name,
            'fruits': self.fruits.as_dict(),
        }

m= Market("Grocery market")
m.fruits.add("apple", "red")
m.fruits.add("banana", "yellow")
m.fruits.add("mango", "green")
s = json.dumps(m.as_dict())

print(s)
0 голосов
/ 14 февраля 2020

Я бы удалил класс Fruits и добавил бы метод, подобный следующему, в ваш рыночный класс:

def addFruit(self, name, color):
        self.fruits[name] = color

Затем вы можете вызывать ваши методы следующим образом:

m.addFruit("apple", "red")
m.addFruit("banana", "yellow")
m.addFruit("mango", "green")

После выполнения если вы получите следующий вывод:

{"name": "Grocery market", "fruits": {"apple": "red", "banana": "yellow", "mango": "green"}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...