Python dataclasses_json: могу ли я хранить много ссылок на один объект? - PullRequest
0 голосов
/ 02 октября 2018

Я хочу использовать @dataclass_json декоратор для хранения моих @dataclass экземпляров.

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

Это можно легко сделать, когда объект класса данных находится впамяти, но когда я пытаюсь сохранить его в JSON, он сохраняет копию экземпляра вместо ссылки на него.Можно как-нибудь с этим справиться?

PS Вот мой пример кода:

from dataclasses import dataclass
from dataclasses_json import dataclass_json

from typing import List

@dataclass_json
@dataclass
class RadarSettings:
    freq: float = 10e9
    prf: float = 1e-3


@dataclass_json
@dataclass
class Radar:
    name: str = ""
    preset_settings: RadarSettings = None  # Here should be references to some boilerplate preset settings for many radars
    custom_settings: RadarSettings = None  # And here should be the custom settings to this current radar


@dataclass_json
@dataclass
class RadarScene:
    name: str = ""
    radars: List["Radar"] = None


preset = RadarSettings()

radar1 = Radar(name="mega search mode radar from hell", preset_settings=preset)

radar2 = Radar(name="satanic sensor array radar", preset_settings=preset)

# The preset_settings is one same object for both radars! If I modify it, the modifications will be applied to both radars
print(id(radar1.preset_settings), id(radar2.preset_settings))


scene_to_save = RadarScene(name="Infernal scene", radars=[radar1, radar2])

loaded_scene = RadarScene.from_json(scene_to_save.to_json())

print(id(loaded_scene.radars[0]), id(loaded_scene.radars[1])) 
# Alas! Here will be two instances of preset_settings saved. I need one =(

1 Ответ

0 голосов
/ 02 октября 2018

Описанная вами проблема - ожидаемое поведение.Когда вы сохраняете ваши данные в формате json, вы получаете строковое представление данных в виде простого текста.

Вы можете решить проблему, по крайней мере, несколькими подходами.

Метод 1.

Загрузка RadarScene данных, создание preset = RadarSettings(), итерация по всем Radar s в RadarScene и обновление атрибута preset_settings: radar.preset_settings = preset.Этот метод может быть инкапсулирован в класс RadarScene, поэтому вы можете вызывать его сразу после загрузки данных.

Метод 2.

Создать новый singleton класс RadarSettingsDefault, унаследованный отRadarSettings и изменить Radar класс: preset_settings: RadarSettingsDefault = None.

...