【问题标题】:Trying to load pickled data to a list isn't appending properly尝试将腌制数据加载到列表中未正确附加
【发布时间】:2019-08-02 01:32:04
【问题描述】:

我正在编写一个待办事项列表应用程序,并存储类对象task 我正在挑选一个已创建对象的列表。但是,当我加载数据时,列表显示为空。我构造它的方式是为每个会话创建一个空列表,然后附加泡菜文件的内容。当创建新任务时,它们会被附加,然后整个列表会被附加,然后重新加载。

这是我的第一个真正的软件项目,所以我的代码看起来很粗糙。我查看了它,找不到任何明显的错误,但显然我做错了什么。

以下是相关代码:

import _pickle as pickle
import os.path
from os import path
from datetime import datetime

#checks if data exists, and creates file if it does not
if path.exists('./tasks.txt') != True:
    open("./tasks.txt", 'wb')
else:
    pass

#define class for tasks
class task:
    def __init__(self, name, due, category):
        self.name = name
        self.due = datetime.strptime(due, '%B %d %Y %I:%M%p')
        self.category = category
    def expand(self): # returns the contents of the task
        return str(self.name) + " is due in " + str((self.due - datetime.now()))

data = []
# load data to list
def load_data():
    with open('tasks.txt', 'rb') as file:
        while True:
            data = []
            try:
                data.append(pickle.load(file))
            except EOFError:
                break
...

# returns current task list
def list_tasks():
    clear()
    if not data:
        print("Nothing to see here.")
    else:
        i = 1
        for task in data:
            print("%s. %s" % (i, task.expand()))
            i = i+1

#define function to add tasks
def addTask(name, due, category):
    newTask = task(name, due, category)
    data.append(newTask)
    with open('./tasks.txt', 'wb') as file:
        pickle.dump(data, file)
    load_data()
    list_tasks()

...

load_data()
list_tasks()
startup()
ask()

【问题讨论】:

  • 如果删除 data = [] 循环中的 data = [] 行会怎样?
  • @Kevin 啊,我现在看到了问题所在。但是,我现在明白了:Traceback (most recent call last): File "/Users/john/Developer/todo/main.py", line 77, in <module> list_tasks() File "/Users/john/Developer/todo/main.py", line 43, in list_tasks print("%s. %s" % (i, task.expand())) AttributeError: 'list' object has no attribute 'expand'
  • 大胆猜测,但也许将行从 data.append(pickle.load(file)) 更改为 data.extend(pickle.load(file)) 会有所帮助吗?在测试之前,您可能需要删除 tasks.txt 文件以确保它没有结构不正确的数据。
  • @Kevin 工作!回答,我会检查标记它。非常感谢。

标签: python serialization pickle


【解决方案1】:
data = []
# load data to list
def load_data():
    with open('tasks.txt', 'rb') as file:
        while True:
            data = []
            try:
                data.append(pickle.load(file))
            except EOFError:
                break

第二个data = [] 看起来不对。在函数内部和外部拥有data = [] 会创建两个data 对象,而您要附加的对象将无法在其他任何地方访问。即使它可以访问,它仍然是空的,因为它在 while 循环的每次迭代中都被重置为 []。尝试擦除内部data = []。那么data.append调用会影响全局可见的data,其内容不会在每次循环中重置。

此外,根据您的其余代码,data 应该是一个任务列表。但是如果你选择任务列表然后运行data.append(pickle.load(file)),那么data 将是一个任务列表列表。保持平稳的一种方法是使用extend 而不是append

data = []
# load data to list
def load_data():
    with open('tasks.txt', 'rb') as file:
        while True:
            try:
                data.extend(pickle.load(file))
            except EOFError:
                break

我认为也可以通过单个 load 调用加载数据,而不是循环中的多次调用。这取决于您的 tasks.txt 文件是单个 pickle.dump 调用的结果,还是您在文件以“附加”模式打开时通过多个 pickle.dump 调用多次附加文本。

def load_data():
    with open('tasks.txt', 'rb') as file:
        return pickle.load(file)
data = load_data()

【讨论】:

    猜你喜欢
    • 2015-03-20
    • 2016-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    • 1970-01-01
    相关资源
    最近更新 更多