【问题标题】:python 3 will not find key in dict from msgpackpython 3 不会在 msgpack 的 dict 中找到键
【发布时间】:2018-04-08 04:42:25
【问题描述】:

为什么在 python3 中会发生这种情况?

1) 我从 redis 获取 msgpack 数据

2) 我打开包装得到以下内容

3) 返回的类型是一个dict:

meta = msgpack.unpackb(data[1])
print(type(meta))
<class 'dict'>

 meta = {b'api_key': b'apikey1',
        b'sensor_id': b'sid1',
        b'version': b'1.0'}

如果我运行以下命令: sensor_meta['sensor_id']

{b'api_key': b'apikey1',
 b'sensor_id': b'sid1',
 b'version': b'1.0'}
Traceback (most recent call last):
  File "/Users//worker.py", line 247, in <module>
    print(meta['sensor_id'])
KeyError: 'sensor_id'

但如果我使用 sensor_meta[b'sensor_id'] 那么它可以工作。

什么是“b”,我怎样才能摆脱它?如何转换整个对象以便没有 b ?

所以如果我执行以下操作:

   print(type(meta['sensor_id']))
   <class 'bytes'>

为什么是字节以及它是如何到达那里的?每次我想在哈希中使用键时,我都不会附加 b。

谢谢

【问题讨论】:

  • 你能不能也给data[1]添加信息
  • 无关...data[1] 是我要解压的数据并列出
  • 但我正式定义了元
  • 你在data[1]有什么类型的数据?

标签: python-3.x msgpack


【解决方案1】:

如注释中提到的here

字符串和二进制类型 在过去,msgpack 不区分字符串 和二进制类型,如 Python 1。表示字符串的类型和 二进制类型被命名为 raw。

msgpack 目前可以区分字符串和二进制类型。但它不是 像 Python 2。Python 2 添加了 unicode 字符串。但是 msgpack 重命名为 raw 到 str 并添加 bin 类型。这是因为保持与数据的兼容性 由旧库创建。 raw 用于文本而不是二进制。

目前,虽然 msgpack-python 支持新的 bin 类型,但默认设置 不使用它并将原始解码为字节而不是 unicode (str in Python 3)。

您可以使用 Packer 中的 use_bin_type=True 选项来更改此设置,并且 Unpacker 中的 encoding=”utf-8” 选项。

>>> import msgpack
>>> packed = msgpack.packb([b'spam', u'egg'], use_bin_type=True)
>>> msgpack.unpackb(packed, encoding='utf-8') ['spam', u'egg']

您可以在解包时定义编码以将字节转换为字符串。

msgpack.unpackb(data[1], encoding='utf-8')

【讨论】: