【问题标题】:How to serialize hash objects in Python如何在 Python 中序列化哈希对象
【发布时间】:2012-01-22 16:19:42
【问题描述】:

如何序列化散列对象?,我使用 shelve 来存储大量对象。

层次结构:

- user
    - client
    - friend

user.py:

import time
import hashlib
from localfile import localfile

class user(object):
    _id = 0
    _ip = "127.0.0.1"
    _nick = "Unnamed"
    _files = {}
    def __init__(self, ip="127.0.0.1", nick="Unnamed"):
        self._id = hashlib.sha1(str(time.time()))
        self._ip = ip
        self._nick = nick
    def add_file(self, localfile):
        self._files[localfile.hash] = localfile
    def delete_file(self, localfile):
        del self._files[localfile.hash]

if __name__ == "__main__":
    pass

client.py:

from user import user
from friend import friend

class client(user):
    _friends = []
    def __init__(self, ip="127.0.0.1", nick="Unnamed"):
        user.__init__(self, ip, nick)
    @property
    def friends(self):
        return self._friends
    @friends.setter
    def friends(self, value):
        self._friends = value
    def add_friend(self, client):
        self._friends.append(client)
    def delete_friend(self, client):
        self._friends.remove(client)

if __name__ == "__main__":
    import shelve

    x = shelve.open("localfile", 'c')

    cliente = client()
    cliente.add_friend(friend("127.0.0.1", "Amigo1"))
    cliente.add_friend(friend("127.0.0.1", "Amigo2"))

    x["client"] = cliente
    print x["client"].friends

    x.close()

错误:

facon@facon-E1210:~/Documentos/workspace/test$ python client.py
Traceback (most recent call last):
  File "client.py", line 28, in <module>
    x["client"] = cliente
  File "/usr/lib/python2.7/shelve.py", line 132, in __setitem__
    p.dump(value)
  File "/usr/lib/python2.7/copy_reg.py", line 70, in _reduce_ex
    raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle HASH objects

已编辑

添加了 user.py。

【问题讨论】:

  • 不是每个模块都需要if __name__ == '__main__' 块,在 user.py 中没用
  • 你是对的,用户应该是一个抽象类。

标签: python serialization hash shelve


【解决方案1】:

由于您不能用shelve 序列化HASH 对象,因此您必须以不同的方式提供相同的信息。例如,您只能保存哈希的摘要。

【讨论】:

  • 我需要两个东西,键(字符串)和元素(可以腌制的对象)。我正在考虑将这两个元素放在 2 个列表中,一个用于键,另一个用于元素。但不知道以后能不能正确加入列表。
  • 然后使用字典或包含 2 个元素的元组列表。
  • 天哪!,我是个傻瓜,我只需要像你说的那样改变这个:self._id = hashlib.sha1(str(time.time())) 到 self._id = hashlib .sha1(str(time.time())).hexdigest() 然后可以腌制对象。我认为哈希已经是一个字符串。谢谢!!!!
  • :) 典型。您还可以使用HASH 对象的digest() 方法。 hexdigest() 的结果需要两倍的字节(40 而不是 20),但它包含相同的信息。除非您想打印出哈希值,否则您可能可以这样做……但这完全是您的选择。
【解决方案2】:

cliente 中的某些东西,client 类的实例,是不可提取的。 这是list of those types which are picklable

您发布的代码未显示 cliente 包含的不可提取的内容。但是您可以通过删除不需要的 unpicklable 属性来解决问题,或者通过定义 __getstate____setstate 使 client 可以选择来解决问题。

【讨论】:

  • 我发布了从客户端继承的类,它可能包含该“哈希元素”,用户,请现在检查。我也接受任何批评以改进我的代码。
猜你喜欢
  • 1970-01-01
  • 2012-01-28
  • 2011-11-16
  • 1970-01-01
  • 2013-06-25
  • 2019-02-19
  • 1970-01-01
  • 2015-06-16
  • 2012-06-25
相关资源
最近更新 更多