简体   繁体   English

在python中从酸洗中排除对象的字段

[英]Exclude object's field from pickling in python

I would like to avoid pickling of certain fields in an instance of a class.我想避免在类的实例中对某些字段进行酸洗。 Currently, before pickling I just set those fields to None, but I wonder whether there's more elegant solution?目前,在酸洗之前,我只是将这些字段设置为无,但我想知道是否有更优雅的解决方案?

One way to handle instance attributes that are not picklable objects is to use the special methods available for modifying a class instance's state: __getstate__() and __setstate__() .处理非picklable对象的实例属性的一种方法是使用可用于修改类实例状态的特殊方法: __getstate__()__setstate__() Here is an example这是一个例子

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

When an instance of Foo is pickled, Python will pickle only the values returned to it when it calls the instance's __getstate__() method.Foo的实例被腌制时,Python 只会在调用实例的__getstate__()方法时腌制返回给它的值。 Likewise, during unpickling, Python will supply the unpickled values as an argument to the instance's __setstate__() method.同样,在 unpickling 期间,Python 将提供 unpickled 值作为实例的__setstate__()方法的参数。 Inside the __setstate__() method we are able to recreate the file object based on the name and position information we pickled, and assign the file object to the instance's logfile attribute.__setstate__()方法中,我们能够根据我们腌制的名称和位置信息重新创建文件对象,并将文件对象分配给实例的日志文件属性。

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

文档中有一个示例可以解决您的__getstate____setstate__问题。

Pickling uses the object's __getstate__ and __setstate__ methods; __getstate__使用对象的__getstate____setstate__方法; you can override them and ignore the fields you want.您可以覆盖它们并忽略您想要的字段。

# 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}")

Output:输出:

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

You can find another example here: https://docs.python.org/3/library/pickle.html#handling-stateful-objects你可以在这里找到另一个例子: https : //docs.python.org/3/library/pickle.html#handling-stateful-objects

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM