首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >numpy数组cPickle转储的默认编码是拉丁语-1吗?

numpy数组cPickle转储的默认编码是拉丁语-1吗?
EN

Stack Overflow用户
提问于 2020-03-03 02:47:20
回答 1查看 189关注 0票数 0

numpy数组cPickle转储的默认编码是拉丁语-1吗?如果是这样,我可以在哪里得到确认。对于rest,它看起来像是utf-8编码。对于numpy.array,此操作失败

代码语言:javascript
复制
In [45]: b = cPickle.dumps(('.'.join(('test',)), (numpy.array([1007261]), True, True), {}), protocol=0)                                                          

In [46]: b                                                                                                                                                       
Out[46]: b'(Vtest\np0\n(cnumpy.core.multiarray\n_reconstruct\np1\n(cnumpy\nndarray\np2\n(I0\ntp3\nc_codecs\nencode\np4\n(Vb\np5\nVlatin1\np6\ntp7\nRp8\ntp9\nRp10\n(I1\n(I1\ntp11\ncnumpy\ndtype\np12\n(Vi8\np13\nI0\nI1\ntp14\nRp15\n(I3\nV<\np16\nNNNI-1\nI-1\nI0\ntp17\nbI00\ng4\n(V\x9d^\x0f\\u0000\\u0000\\u0000\\u0000\\u0000\np18\ng6\ntp19\nRp20\ntp21\nbI01\nI01\ntp22\n(dp23\ntp24\n.'

In [47]: b = '(Vtest\np0\n(cnumpy.core.multiarray\n_reconstruct\np1\n(cnumpy\nndarray\np2\n(I0\ntp3\nc_codecs\nencode\np4\n(Vb\np5\nVlatin1\np6\ntp7\nRp8\ntp9\nR
    ...: p10\n(I1\n(I1\ntp11\ncnumpy\ndtype\np12\n(Vi8\np13\nI0\nI1\ntp14\nRp15\n(I3\nV<\np16\nNNNI-1\nI-1\nI0\ntp17\nbI00\ng4\n(V\x9d^\x0f\\u0000\\u0000\\u0000\
    ...: \u0000\\u0000\np18\ng6\ntp19\nRp20\ntp21\nbI01\nI01\ntp22\n(dp23\ntp24\n.'              
In [48]: cPickle.loads(b.encode('utf-8'), encoding='utf-8')                                                                                                      
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-48-58c17196f700> in <module>
----> 1 cPickle.loads(b.encode('utf-8'), encoding='utf-8')
ValueError: buffer size does not match array size
In [50]: cPickle.loads(b.encode('latin1'), encoding='latin1')                                                                                                    
Out[50]: ('test', (array([1007261]), True, True), {})

我从一个应用程序转储数据,然后从另一个应用程序读取数据。因此,在使用cPickle加载它们之前,我必须将字符串转换为字节。我认为cPickle.dump在py3中总是使用utf-8编码,这让我很好奇。有没有人能帮我解释一下。

EN

回答 1

Stack Overflow用户

发布于 2020-03-03 06:10:30

不是酸菜,而是你一开始就用拉丁语-1。

当你从pickle.dumps的输出,也就是。将Out46中的b设置为您在下一条语句中指定给b的值,然后将类型从bytes更改为str。您进行此更改的方式等同于b = b.decode('latin1')

例如,原始b包含序列b'(V\x9d^\x0f' (在最后三分之一)。让我们用它来看看发生了什么:

代码语言:javascript
复制
>>> b = b'(V\x9d^\x0f'
>>> b.decode('latin1')
'(V\x9d^\x0f'

这是您在语句47中分配给b的内容(接近第二行的末尾)。在视觉上,您删除了字符串文字的b前缀。实际上,您可以使用拉丁-1将bytes对象解码为str。这是因为拉丁-1具有字节值到Unicode代码点的1:1映射。

它现在是一个str。但是pickle需要一个bytes对象,所以您需要重新编码。但是,如果您使用UTF-8进行编码,您将得到一个与原始对象不同的bytes对象:

代码语言:javascript
复制
>>> b.decode('latin1').encode('utf8')
b'(V\xc2\x9d^\x0f'

现在有了\xc2\x9d,而不是\x9d

如果你用拉丁语-1编码,你会得到和之前一样的结果:

代码语言:javascript
复制
>>> b.decode('latin1').encode('latin1')
b'(V\x9d^\x0f'

但是:,我完全不明白为什么这种往返转换是必要的。实际上,没有必要将pickle.dumps的输出解码为str。你可以一直把这个值保存在一个字节字符串中。使用正确的类型:bytes用于二进制数据(如pickle转储),str用于文本(与pickle转储不同)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60494867

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档