Python:如何在文件中保存包含对象的列表?

时间:2013-06-12 23:09:06

标签: python class object input output

我试图创建不同的对象(使用Clases和对象)并将它们保存在文件中以便稍后编辑或检索它们。不过这看起来如何。

GlobalCategories=[]
GlobalContent=[]
def LoadData(x,y):
   import pickle
   with open('bin.dat') as f:
       x,y = pickle.load(f)


def SaveData(x,y):
   import pickle
   with open('bin.dat', 'wb') as f:
      pickle.dump([x,y], f)

def Loader(x,y):
     try:
          LoadData(x,y)
     except:
          SaveData(x,y)

这个保存的片段显示了我如何保存列表中的信息(tema是类,其他东西是该类的方法):

newtheme=Tema()
newtheme.setInfo_name(newstr)
newtheme.setInfo_code(newcode)
GlobalCategories.append(newtheme)
SaveData(GlobalContent,GlobalCategories)

X和Y是我存储对象的全局列表。(我注意到它将方向保存在每个对象的内存中) 当我第一次运行它时,它创建文件并将信息保存在文件中,但是如果我关闭它,尝试再次运行它并加载信息,程序将删除信息,并再次创建文件,所以任何事情都是存储已经消失了。

我不知道这是否是一种存储物品的方式,或者是否有更好的方式,所以任何建议都非常受欢迎。

@abernert:谢谢abarnert!我想要做的是保存一个包含两个列表的列表。例如,一个列表将保存一个品牌(丰田,尼桑等),另一个列出汽车模型(苔原,穆拉诺)。现在每个元素都是我在创建时添加到列表中的对象。 newtheme=Theme() newtheme.setInfo_name(newstr) GlobalCategories.append(newtheme) 这是我如何在全局列表中保存对象。 GlobalCategories是我想在我关闭程序之后加载的两个列表中的一个(它就像示例中的汽车公司列表)。现在,我有问题是在关闭并重新启动程序后从列表中加载对象,因为当我还没有关闭shell时,我能够从列表中检索和编辑它们。 一旦我启动程序,我需要在各自的列表中加载和存储品牌和汽车对象,以便我以后可以操作它们。 再次感谢阿瑟讷!

2 个答案:

答案 0 :(得分:6)

如果您没有尝试使用LoadDataSaveData函数的上下文,很难知道问题所在。但是,这是一个小型的演示,可以完成我认为你想要的。

import pickle
import random

def load_data():
    try:
        with open("bin.dat") as f:
            x, y = pickle.load(f)
    except:
        x, y = [], []
    return x, y

def save_data(data):
    with open("bin.dat", "wb") as f:
        pickle.dump(data, f)

if __name__ == "__main__":
    x, y = load_data()
    print x, y
    x.append(random.randint(1, 10))
    y.append(random.randint(1, 10))
    save_data([x, y])

从连续跑的输出

[] []
[9] [9]
[9, 10] [9, 9]
[9, 10, 2] [9, 9, 4]
[9, 10, 2, 5] [9, 9, 4, 1]
[9, 10, 2, 5, 6] [9, 9, 4, 1, 9]
[9, 10, 2, 5, 6, 10] [9, 9, 4, 1, 9, 1]

答案 1 :(得分:0)

很难确定,但我猜你的问题是你正在编写一个二进制文件,然后尝试将其作为文本读回来,而你在Windows上使用Python 2.x.

在此代码中:

def LoadData(x,y):
    import pickle
    with open('bin.dat') as f:
        x,y = pickle.load(f)

如果碰巧在二进制pickle流中有任何LF换行符,则将文件作为文本打开会将它们转换为CR / LF对。这将导致泡菜无效,因此它会引发异常。

在此代码中:

def Loader(x,y):
     try:
          LoadData(x,y)
     except:
          SaveData(x,y)

...你只是吞下任何异常并保存一些空值。

您可能只想在此处理文件未找到的错误(IOErrorOSErrorFileNotFoundError,具体取决于您的Python版本。)

但是你肯定希望将异常放入一个变量来帮助调试你的问题,如下所示:

def Loader(x,y):
     try:
          LoadData(x,y)
     except Exception as e:
          SaveData(x,y)

您可以在调试器的SaveData行上添加断点,或者只需添加print(e)行并观察输出,看看为什么要到达那里。


与此同时,即使您解决了这个问题,LoadData也永远不会做任何有用的事情。分配x,y = pickle.load(f)只会重新绑定局部变量xy。它们与Loader中的局部变量具有相同的名称这一事实并不意味着Loader的变量会发生变化。他们过去也没有提到相同的价值这一事实。

Python没有“引用变量”或“输出参数”。执行此操作的常规方法是仅返回要传递给调用者的值:

def LoadData():
    import pickle
    with open('bin.dat') as f:
        x,y = pickle.load(f)
    return x,y

当然Loader必须正确地调用它:

def Loader(x,y):
     try:
          x,y = LoadData()
     except:
          SaveData(x,y)

您在Loader中又遇到了完全相同的问题,因此您需要在那里再次修复它,并在其调用方中。