【问题标题】:Store self appending Python object in human readable file将自附加 Python 对象存储在人类可读文件中
【发布时间】:2017-05-28 03:01:29
【问题描述】:

我继承了一个 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 问题不同,因为我认为将我的类转换为 Dictionary 会丢失代码中其他地方所需的关键功能。

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

【问题讨论】:

  • 将其放入字典而不是单独的字段中,您将能够使用 json 或 str() 序列化 dict,并使用 json 或 ast.literal_eval 将其读回。
  • 我对字典的担忧是我失去了代码的自我附加部分,以及我目前拥有的对象的整洁嵌套功能,这是代码的电子邮件部分所必需的(未列出这里)。本质上,该代码对Person 中的所有人进行了排序,并弹出了最长时间没有做蛋糕的人。然后它会弹出名字,给他们发电子邮件,等待回复,如果有必要,会转移到下一个人等等。我不能用字典做到这一点,可以吗?

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


【解决方案1】:

我会使用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)

【讨论】:

  • 您介意提供更多扩展示例吗?我不确定如何将我的对象转换为 json 所需的那种数据字符串。
  • 我很抱歉,亚历克斯。这并不容易。更新了答案
猜你喜欢
  • 2015-01-25
  • 1970-01-01
  • 2015-03-03
  • 1970-01-01
  • 1970-01-01
  • 2013-05-24
  • 2016-04-16
  • 2013-09-29
  • 2015-07-14
相关资源
最近更新 更多