从python中的pickling中排除对象的字段

时间:2010-02-27 01:56:55

标签: python pickle

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

3 个答案:

答案 0 :(得分:29)

处理非可选对象的实例属性的一种方法是使用可用于修改类实例状态的特殊方法: 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实例被pickle时,Python会在调用实例的 getstate ()方法时仅选择返回给它的值。同样,在unpickling期间,Python将提供unpickled值作为实例的 setstate ()方法的参数。在 setstate ()方法中,我们可以根据我们选择的名称和位置信息重新创建文件对象,并将文件对象分配给实例的logfile属性。

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

答案 1 :(得分:8)

有一个示例here可以解决您__getstate____setstate__的问题。

答案 2 :(得分:2)

酸洗使用对象的__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