将自身附加的Python对象存储在人类可读文件中

时间:2017-01-12 20:53:23

标签: python xml file-io pickle human-readable

我继承了一个Python脚本,每周都会选择人们为办公室制作蛋糕。在这样做的过程中,它会保留一份想要制作蛋糕的人员列表,以及他们最后一次制作蛋糕和其他东西时的电子邮件地址。它将所有这些存储在下面的自附加对象中:

import datetime as dt
import pickle

class Person():
    name_list=[]
    def __init__(self,name,email):
        self.name=name
        self.email=email
        self.lastCake=dt.datetime.strptime('01011990', '%d%m%Y').date()
        self.weight=0
        self.update_weight()
        Person.name_list.append(self)

    def __repr__(self):
        return "%s: %i"%(self.name,self.weight)

    def __str__(self):
        return "%s: %i"%(self.name,self.weight)

    def __lt__(self,other):
        return self.weight < other.weight

    def update_weight(self,now=dt.date.today()):
        days_since_cake=now-self.lastCake
        self.weight=int(days_since_cake.days)

def make_cake_list():
    Person('Alice','FAKE@FAKE.com')
    Person('Bob','FAKE@FAKE.com')
    Person('Cath','FAKE@FAKE.com')
    Person('Dave','FAKE@FAKE.com')

由于此脚本监视并发送/接收电子邮件,因此它会不断运行,因此在系统重新启动/断电/崩溃时偶尔会关闭。这意味着Person对象是从文件写入/读取的,而Pickle用于使用这两个函数执行此操作:

def save_cake_list(people):
    with open("cake_list.dat",'w') as f:
        pickle.dump(people,f)

def read_cake_list():
    with open("cake_list.dat",'r') as f:
        return pickle.load(f)

所有相当标准。除了它的设置方式以及它如何维护它的列表之外,它是一个真正的猪,可以添加新的人,然后跟踪你添加的人(一些名称是硬编码的,但我想摆脱这个功能。我不太经常在脚本的内容中捅,越好!)。而使用Pickle,人类无法读取/编辑它创建的文件。

那么,有没有办法获取对象Person(及其最重要的自我附加name_list)并将其传递给人类可读文件? XML文件浮现在脑海中,但我看过的方法似乎没有处理我在这里的自添加列表系统,我没有很多经验。

有一个addPerson函数不是太糟糕,所以我总是可以存储一个人和电子邮件的列表,读取它并将其推入函数中,但我会失去重量(多长时间以来)一个人最后做蛋糕)。

思想?

编辑:我不相信这与其他地方的Dictionary to Serial to Dictionary问题相同,因为我认为将我的Class转换为Dictionary会丢失代码中其他地方所需的关键功能。

但是,我不熟悉字典,所以如果我错了,请提供一个MWS并解释为什么字典会起作用。

1 个答案:

答案 0 :(得分:0)

我会使用json作为存储数据的格式。然后,如果需要,您可以利用Web解决方案。 您可以使用json模块,但它需要一些钩子,所以我会选择最简单的选项。我使用jsonpickle来序列化和反序列化复杂的python对象。这是一个例子

import datetime as dt
import jsonpickle

class Person():
    name_list=[]
    def __init__(self,name,email):
        self.name=name
        self.email=email
        self.lastCake=dt.datetime.strptime('01011990', '%d%m%Y').date()
        self.weight=0
        self.update_weight()
        Person.name_list.append(self)

    def default(self):
        return self.__dict__

    def __repr__(self):
        return "%s: %i"%(self.name,self.weight)

    def __str__(self):
        return "%s: %i"%(self.name,self.weight)

    def __lt__(self,other):
        return self.weight < other.weight

    def update_weight(self,now=dt.date.today()):
        days_since_cake=now-self.lastCake
        self.weight=int(days_since_cake.days)

def make_cake_list():
    persons = list()
    persons.append(Person('Alice','FAKE@FAKE.com'))
    persons.append(Person('Bob','FAKE@FAKE.com'))
    persons.append(Person('Cath','FAKE@FAKE.com'))
    persons.append(Person('Dave','FAKE@FAKE.com'))
    return persons

persons = make_cake_list()
print jsonpickle.encode(persons, unpicklable=False)