【问题标题】:"UnicodeDecodeError: 'charmap' codec can't decode" error in pickle load“UnicodeDecodeError:'charmap'编解码器无法解码”泡菜加载错误
【发布时间】:2017-05-06 15:06:31
【问题描述】:

我正在尝试将一组 Tweet 对象保存在文件中。 Tweet 类实例包含 utf8 编码字符。你可以看到下面的代码:

class Tweet:
    author='';
    text='';
    time='';
    date='';
    timestamp='';

with open('tweets.dat','wb') as f:
     pickle.dump(all_tweets,f)

with open('tweets.dat') as f:
   all_tweets = pickle.load(f)

当我运行代码时,它会在 pickle.load(f) 行返回一个异常,说明:

UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 25: character maps to <undefined>

我的机器规格:

Python 3.5.2 |Anaconda 4.2.0(64 位)| (默认,2016 年 7 月 5 日, 11:41:13) [MSC v.1900 64 位 (AMD64)] 在 win32 上

【问题讨论】:

  • 为什么要以二进制方式写入文件并以文本方式读取?
  • 我想检索我的对象然后使用它们。虽然我在这里提到了简单的情况,但 Tweet 类也可能包含非文本属性。
  • 您在写入时替换了整个 DAT 文件,但您希望将其与外部编码/解码系统一起使用。您还记得“创建此文件时使用了哪种解码方式吗?” .大多数人回答“不知道!” ,因为os_encodingpython encodepython decode 模式在哪里?

标签: python encoding utf-8 pickle


【解决方案1】:

在 Python 3 中,pickle 模块期望底层文件对象接受或返回 bytes。您正确地以二进制模式打开文件进行写入,但未能执行相同的读取操作。阅读的部分应该是:

with open('tweets.dat', 'rb') as f:
   all_tweets = pickle.load(f)

参考:摘自pickle.load(fd)的文档:

...因此文件可以是为二进制读取而打开的磁盘文件、io.BytesIO 对象或任何其他满足此接口的自定义对象。

【讨论】:

  • 谢谢。不幸的是,它不起作用。它返回另一个错误“AttributeError: Can't get attribute 'Tweet' on”
  • @CoderInNetwork:您应该编辑您的问题以添加minimal reproducible example。我对您的问题中当前显示的内容进行了稍微修改的对象(使用非 ascii 数据)进行了测试,并且它有效。 Pickle 是一个众所周知且经过良好测试的模块,如果您不知道确切如何使用它,我们将无法为您提供帮助。
  • 当对 load() 使用 'rb' 模式时,字符串被视为字节,并且考虑到未腌制的数据大小,将这些字节转换回字符串可能会出现问题
  • 这个和pickle.load(f,encoding='latin1')一起为我解决了这个问题
猜你喜欢
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-20
  • 2021-10-12
  • 1970-01-01
相关资源
最近更新 更多