简体   繁体   English

如何持久化和加载数据类的所有属性

[英]How to persist and load all attributes of a dataclass

I want to persist all attributes of an object which is an instance of a dataclass.我想保留 object 的所有属性,它是数据类的一个实例。 Then I want to load back that object from the files that I persisted.然后我想从我保留的文件中加载回 object。

Here it is an example that fullfills the task:这是一个完成任务的例子:

from dataclasses import dataclass
import pickle


@dataclass
class Circle:
    radius: float
    centre: tuple

    def save(self, path: str):
        name = ".".join(("radius", "pkl"))
        with open("/".join((path, name)), "wb") as f:
            pickle.dump(self.radius, f)
        name = ".".join(("centre", "pkl"))
        with open("/".join((path, name)), "wb") as f:
            pickle.dump(self.centre, f)

    @classmethod
    def load(cls, path):
        my_model = {}
        name = "radius"
        file_name = ".".join((name, "pkl"))
        with open("\\".join((path, file_name)), "rb") as f:
            my_model[name] = pickle.load(f)
        name = "centre"
        file_name = ".".join((name, "pkl"))
        with open("\\".join((path, file_name)), "rb") as f:
            my_model[name] = pickle.load(f)
        return cls(**my_model)
>>> c = Circle(2, (0, 0))
>>> c.save(r".\Circle")
>>> c_loaded = Circle.load(r".\Circle")
>>> c_loaded == c
True

As you can see I need to repeat the same code for every attribute, what is a better way to do it?如您所见,我需要为每个属性重复相同的代码,更好的方法是什么?

In the save method it use self.__dict__ .在保存方法中,它使用self.__dict__ That contains all attribute names and values as a dictionary.它包含作为字典的所有属性名称和值。 Load is a classmethod so there is no __dict__ at that stage. Load 是一个类方法,所以在那个阶段没有__dict__ However, cls.__annotations__ contains attribute names and types, still stored in a dictionary.但是, cls.__annotations__包含属性名称和类型,仍然存储在字典中。

Here it is the end result:这是最终结果:

from dataclasses import dataclass
import pickle

@dataclass
class Circle:
    radius: float
    centre: tuple

    def save(self, path):
        for name, attribute in self.__dict__.items():
            name = ".".join((name, "pkl"))
            with open("/".join((path, name)), "wb") as f:
                pickle.dump(attribute, f)

    @classmethod
    def load(cls, path):
        my_model = {}
        for name in cls.__annotations__:
            file_name = ".".join((name, "pkl"))
            with open("/".join((path, file_name)), "rb") as f:
                my_model[name] = pickle.load(f)
        return cls(**my_model)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM