【问题标题】:Python3 unpickle a string representation of bytes objectPython3 unpickle 字节对象的字符串表示
【发布时间】:2018-10-19 10:51:15
【问题描述】:

有没有一种好方法可以加载表示为字符串的字节对象,以便可以取消它?

基本示例

这是一个愚蠢的例子:

import pickle

mydict = { 'a': 1111, 'b': 2222 }
string_of_bytes_obj = str(pickle.dumps(mydict)) # Deliberate string representation for this quick example.

unpickled_dict = pickle.loads(string_of_bytes_obj) # ERROR!  Loads takes bytes-like object and not string.

尝试解决方案

一个解决方案当然是eval这个字符串:

unpickled_dict = pickle.loads(eval(string_of_bytes_obj))

但是,eval 似乎是错误的,尤其是当字符串可能来自网络或来自文件时。

...

对更好的解决方案有什么建议吗?

谢谢!

【问题讨论】:

  • 我认为最好不要将字节转换为str。有什么办法可以避免这种转换?
  • @soon 我只是在处理来自其他人的文件...肯定会更好地将他们的文件更改为使用二进制数据...但是现在,我无法避免字符串转换.
  • 将pickle与网络数据一起使用不是一个好主意顺便说一句:zopatista.com/plone/2007/11/09/one-cookie-please
  • 你知道文件的编码是什么吗?如果你这样做了,那么你只需要str.encode 解开字符串。如果你不知道,你需要先猜测编码。
  • @JacquesGaudin 不确定我是否理解。字符串的编码是什么?我知道该文件是 utf-8,但我认为给我的只是一种以已知编码获取字符串表示形式的方法,我仍然需要评估......或者你的意思是像@提供的答案Farhan.K?

标签: python python-3.x pickle


【解决方案1】:

出于安全考虑,您可以使用ast.literal_eval 而不是eval

>>> import ast
>>> pickle.loads(ast.literal_eval(string_of_bytes_obj))
{'b': 2222, 'a': 1111}

【讨论】:

  • 谢谢。很好的答案。更安全的评估,只需要一些额外的错误处理。
【解决方案2】:

您可以使用encoding="latin1" 作为str 的参数,然后使用bytes 转换回来:

import pickle

mydict = { 'a': 1111, 'b': 2222 }
string_of_bytes_obj = str(pickle.dumps(mydict), encoding="latin1")

unpickled_dict = pickle.loads(bytes(string_of_bytes_obj, "latin1"))

输出:

>>> print(unpickled_dict)
{'a': 1111, 'b': 2222}

【讨论】:

    【解决方案3】:

    是否有理由需要将它作为 str ?如果您只是将其写入文件,则可以使用 'wb' 而不是 'w'。 (https://pythontips.com/2013/08/02/what-is-pickle-in-python/)

    import pickle
    
    mydict = { 'a': 1111, 'b': 2222 }
    dumped = pickle.dumps(mydict)
    string_of_bytes_obj = str(dumped) # Deliberate string representation for this quick example. 
    
    unpickled_dict = pickle.loads(dumped) 
    

    【讨论】:

    • 不幸的是,不是我的文件,我只是在处理我得到的东西!
    【解决方案4】:

    首先我不会使用泡菜来序列化数据。而是使用 Json。

    我的泡菜解决方案

    import pickle
    
    mydict = { 'a': 1111, 'b': 2222 }
    string_of_bytes_obj = pickle.dumps(mydict) # Deliberate string representation for this quick example.
    print(string_of_bytes_obj)
    unpickled_dict = pickle.loads(string_of_bytes_obj)
    print(unpickled_dict)
    

    但是使用 json

    import json
    
    mydict = { 'a': 1111, 'b': 2222 }
    string_of_bytes_obj = json.dumps(mydict) 
    print(string_of_bytes_obj)
    unpickled_dict = json.loads(string_of_bytes_obj)
    print(unpickled_dict)
    

    我强烈推荐你使用 json 来序列化你的数据

    【讨论】:

      猜你喜欢
      • 2019-07-20
      • 2019-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-09
      • 2018-07-23
      相关资源
      最近更新 更多