通过读取pickle文件获取的字典引发了KeyError的错误。
通过读取pickle文件获取的字典引发了KeyError的错误。
我手头有3个使用pickle转储到3个不同文件的字典。最初我为每个文件编写了一个读取和写入函数,总共有6个函数。所以昨晚我尝试只使用一个读取函数和一个写入函数。我成功实现了写入函数,但读取函数却没有。我从昨晚开始一直在寻找解决这个问题的方法,我已经受够了,所以如果你能提供任何帮助,我将不胜感激。
我是编程/Python的新手,如果你还没有发现的话。这是我正在使用的代码:
w = {} # 作为源代码传递 def writing(filename, source): with open(filename, 'wb') as st: pickle.dump(source, st) def reading(filename, source): with open(filename, 'rb') as st: source = pickle.loads(st.read()) reading('test.txt', w)
我得到的错误是:
Traceback (most recent call last): File "./database.py", line 303, inpw.check_pwd(p) File "./database.py", line 47, in check_pwd if self.pwds[self.user] == hashlib.sha512(self.pwd + self.salt).hexdigest(): KeyError: 'Codex' 这就是我得到的错误,抱歉这个帖子写得不好
出现 KeyError 错误的原因是因为在读取 pickle 文件时,使用的函数没有正确处理文件中可能不存在的键值。在这种情况下,当尝试通过键来检索值时,会出现 KeyError。
解决这个问题的方法是在读取 pickle 文件时,先检查键是否存在,然后再尝试检索值。如果键存在,就更新源字典;如果键不存在,可以选择忽略该键或者抛出自定义的异常。
下面是一个示例的解决方法:
import pickle def reading(filename, source): with open(filename, 'rb') as st: tmp = pickle.loads(st.read()) for key in tmp: if key in source: source[key] = tmp[key] else: # 键不存在时的处理方式,可以选择忽略或者抛出异常 # source[key] = tmp[key] # 忽略不存在的键 # raise KeyError(f"Key '{key}' does not exist") # 抛出自定义异常 # 使用示例 source = {'a': 1, 'b': 2} reading('data.pickle', source) print(source)
在上述示例中,我们首先打开 pickle 文件并将其加载为临时字典 tmp。然后,我们遍历 tmp 的键,检查每个键是否存在于源字典 source 中。如果存在,我们将源字典中对应键的值更新为 tmp 中对应键的值。如果不存在,可以根据实际需求选择忽略该键或者抛出自定义的异常。
通过以上的解决方法,可以避免在读取 pickle 文件时出现 KeyError 错误。
在上面的代码中,定义了一个函数`reading`,这个函数的作用是读取一个pickle文件并返回其中的内容。在函数中,使用`open`函数打开文件,并使用`pickle.loads`函数将文件内容转换为Python对象。然后,将转换后的对象赋值给变量`source`。最后,使用`return`语句返回变量`source`。
然而,在这段代码中存在一个问题。在函数的最后,虽然使用了`return`语句,但是并没有返回`source`。因此,如果调用这个函数,函数将默认返回`None`,而不是我们期望的文件内容。
为了解决这个问题,我们需要将`source`作为函数的返回值。可以在函数的最后加上`return source`语句,这样就可以返回`source`。
修复后的代码如下所示:
def reading(filename, source): with open(filename, 'rb') as st: source = pickle.loads(st.read()) return source
通过上述修改,我们就可以正确地从pickle文件中读取内容并返回了。这样,我们就避免了因为没有返回值而导致的`KeyError`的问题。
在这段对话中,提到了一个问题:使用读取pickle文件的函数检索到的字典,会引发KeyError错误。下面我们来分析一下出现这个问题的原因以及解决方法。
问题的原因是,在给变量source赋值时,只是更新了局部变量source的值,而变量w仍然指向同一个值。这是因为Python中,赋值操作只是将变量与新值进行绑定,并不会改变其他变量与原值的绑定关系。
解决这个问题的方法有几种。其中一种方法是通过返回值来获取反pickle化的结果,并将其赋给全局变量w。具体代码如下:
def reading(filename, source): with open(filename, 'rb') as st: source = pickle.loads(st.read()) return source w = reading(filename, w)
实际上,你甚至不需要传递source参数,可以直接在函数内部将结果赋给局部变量source,并返回它。具体代码如下:
def reading(filename): with open(filename, 'rb') as st: source = pickle.loads(st.read()) return source w = reading(filename)
另一种解决方法是使用字典的update方法来更新source指向的字典。在这种情况下,不需要返回任何值。具体代码如下:
def reading(filename, source): with open(filename, 'rb') as st: source.update(pickle.loads(st.read())) reading(filename, w)
还有一种解决方法是将w变量声明为函数内部的全局变量(但这是最差的解决方法)。具体代码如下:
def reading(filename): global w with open(filename, 'rb') as st: w = pickle.loads(st.read()) reading(filename)
解决了问题之后,建议花些时间来理解为什么这种方法有效,而你之前的解决方法无效。这是使用Python(以及大多数面向对象语言)的一个非常重要的方面。除了上面提供的链接,你还可以参考这个很好的回答。
希望以上解答对你有帮助!