【问题标题】:Exclude object's field from pickling in python从python中的酸洗中排除对象的字段
【发布时间】:2010-02-27 01:56:55
【问题描述】:

我想避免酸洗类实例中的某些字段。 目前,在酸洗之前我只是将这些字段设置为无,但我想知道是否有更优雅的解决方案?

【问题讨论】:

    标签: python pickle


    【解决方案1】:

    处理不可提取对象的实例属性的一种方法是使用可用于修改类实例状态的特殊方法:__getstate__()__setstate__()。这是一个例子

    class Foo(object):
    
        def __init__(self, value, filename):
            self.value = value
            self.logfile = file(filename, 'w')
    
        def __getstate__(self):
            """Return state values to be pickled."""
            f = self.logfile
            return (self.value, f.name, f.tell())
    
        def __setstate__(self, state):
            """Restore state from the unpickled state values."""
            self.value, name, position = state
            f = file(name, 'w')
            f.seek(position)
            self.logfile = f
    

    Foo 的实例被腌制时,Python 将只腌制在调用实例的__getstate__() 方法时返回给它的值。同样,在 unpickling 期间,Python 会将 unpickled 的值作为参数提供给实例的 __setstate__() 方法。在__setstate__() 方法中,我们能够根据我们腌制的名称和位置信息重新创建文件对象,并将文件对象分配给实例的日志文件属性。

    参考:http://www.ibm.com/developerworks/library/l-pypers.html

    【讨论】:

    • 此答案末尾的链接已损坏。
    【解决方案2】:

    有一个示例in the docs 可以解决您使用__getstate____setstate__ 的问题。

    【讨论】:

    • 再次修复链接
    【解决方案3】:

    Pickling 使用对象的__getstate____setstate__ 方法;您可以覆盖它们并忽略您想要的字段。

    # foo.py
    class Foo:
        def __init__(self):
            self.bar = 1
            self.baz = 2
    
        def __getstate__(self):
            state = self.__dict__.copy()
            # Don't pickle baz
            del state["baz"]
            return state
    
        def __setstate__(self, state):
            self.__dict__.update(state)
            # Add baz back since it doesn't exist in the pickle
            self.baz = 0
    
    # main.py
    import pickle
    
    from foo import Foo
    
    
    foo = Foo()
    print(f"Foo bar: {foo.bar} baz: {foo.baz}")
    
    new_foo = pickle.loads(pickle.dumps(foo))
    print(f"New bar: {new_foo.bar} baz: {new_foo.baz}")
    

    输出:

    Foo bar: 1 baz: 2
    New bar: 1 baz: 0
    

    您可以在此处找到另一个示例:https://docs.python.org/3/library/pickle.html#handling-stateful-objects

    【讨论】:

    • 另一个答案使用state 作为tuple,而这个使用它作为dictionary。看来state的类型是由__getstate__的返回类型决定的
    • 请注意,这也会删除__slots__ 中的任何内容,并且如果baz__baz 将不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多