【问题标题】:How to create a persistant class using pickle in Python如何在 Python 中使用 pickle 创建持久类
【发布时间】:2012-02-23 07:52:24
【问题描述】:

python 新手... 我有以下类 Key,它扩展了 dict:

class Key( dict ):

    def __init__( self ):
        self = { some dictionary stuff... }

    def __getstate__(self):
        state = self.__dict__.copy()
        return state

    def __setstate__(self, state):
        self.__dict__.update( state )

我想使用pickle.dump 保存该类的一个实例及其数据,然后使用pickle.load 检索数据。我知道我应该以某种方式更改 getstate 和 setstate,但是,我并不完全清楚我应该如何做到这一点......任何帮助将不胜感激!

【问题讨论】:

    标签: python dictionary persistence pickle


    【解决方案1】:

    我写了一个 dict 的子类来做这个。

    class AttrDict(dict):
        """A dictionary with attribute-style access. It maps attribute access to
        the real dictionary.  """
        def __init__(self, *args, **kwargs):
            dict.__init__(self, *args, **kwargs)
    
        def __getstate__(self):
            return self.__dict__.items()
    
        def __setstate__(self, items):
            for key, val in items:
                self.__dict__[key] = val
    
        def __repr__(self):
            return "%s(%s)" % (self.__class__.__name__, dict.__repr__(self))
    
        def __setitem__(self, key, value):
            return super(AttrDict, self).__setitem__(key, value)
    
        def __getitem__(self, name):
            return super(AttrDict, self).__getitem__(name)
    
        def __delitem__(self, name):
            return super(AttrDict, self).__delitem__(name)
    
        __getattr__ = __getitem__
        __setattr__ = __setitem__
    
        def copy(self):
            return AttrDict(self)
    

    它基本上将状态转换为基本元组,然后再次将其带回 unpickle。

    但请注意,您必须要有原始源文件才能解压。酸洗实际上并不保存类本身,只保存实例状态。 Python 需要重新创建原始类定义。

    【讨论】:

    • 太棒了!谢谢基思!但是,当我尝试 obj = pickle.load 然后打印 obj.self 时仍然出现以下错误: return super(Key, self).__getitem__(name) KeyError: 'self'
    • 如果我只打印 obj 我会得到奇怪的输出 Key({}) 而不是 {}...知道这里可能发生了什么吗?
    • ElfsRUs:后者是因为 repr 方法——Keith 专门将它设计成这样。如果您希望它看起来像 {},可以将其更改为 return "%s" % (dict.__repr__(self),)。至于第一个问题,您能否发布您用于获取该回溯的代码?
    • @DavidRobinson 感谢您的澄清,我正在执行以下操作:key = pickle.load( open( sys.argv[2], "rb" ) ) print key.self.
    • 你最初用来腌制对象的代码是什么?
    猜你喜欢
    • 2015-12-20
    • 1970-01-01
    • 1970-01-01
    • 2015-12-11
    • 2018-01-17
    • 1970-01-01
    • 1970-01-01
    • 2011-03-09
    • 2012-04-05
    相关资源
    最近更新 更多