如何腌制从A继承的B类(具有许多变量)的对象,该对象定义了__setstate__和__getstate__ [英] How to pickle an object of a class B (having many variables) that inherits from A, that defines __setstate__ and __getstate__

查看:83
本文介绍了如何腌制从A继承的B类(具有许多变量)的对象,该对象定义了__setstate__和__getstate__的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是:

class A(object):
    def __init__(self):
        #init
    def __setstate__(self,state):
        #A __setstate__ code here            
    def __getstate__(self):
        #A __getstate__ code here
        return state

class B(A):
    def __init__(self):
        #creates many object variables here

A来自外部库.

硬性解决方案

我想避免

腌制B时,腌制当然会使用类A的__setstate____getstate__方法,因此,为了使腌制工作,我应该执行以下操作:

When pickling B, pickle of course uses class A's __setstate__, __getstate__ methods, so in order for pickle to work I should do something like this:

class B(A):
    def __init__(self):
        #creates many object variables here

    def __setstate__(self,state)
        A.__setstate__(self,state)
        #B __setstate__ code here
        #getting various variables from state for example
        self._a0 = state['a0']
        self._a1 = state['a1']
        #...
        self._a100 = state['a100']
        self._a101 = state['a101']

    def __getstate__(self):
        state = A.__getstate__(self)
        #B __setstate__ code here
        #filling state with various variables  
        #getting various variables from state for example
        state['a0'] =  self._a0
        state['a1'] =  self._a1
        #...
        state['a100'] =  self._a100
        state['a101'] =  self._a101           
        return state

我的问题是:

如何避免在B中定义__setstate____getstate__,以便pickle自己完成酸洗变量的工作? B中的所有变量的类型都是pickle可以自己进行pickle(处理). 因此,如果B不继承自A,则有可能获得良好的结果:

How can I avoid defining __setstate__ and __getstate__ in B so that pickle does the job of pickling variables by itself? All variables in B are of type that pickle may pickle(handle) by itself. So if B didn't inherit from A, it would be possible with good results:

b = B()
path = 'path.temp'
fout = open(path,'w')
pickler = pickl.Pickler(fout)

pickler.dump(b)
fout.close()

fin = open(path,'r')
upickler = pickl.Unpickler(fin)
b = unpickler.load()
fin.close()
#b has all variables

显而易见的解决方案

class B(object):
    def __init__(self):
        #creates many object variables here
        a = A()            

但是我希望B从A继承. 知道如何解决这个问题,或者至少自动解决B中的酸洗/取消酸洗问题吗?

However I would like B to inherit from A. Any idea how to solve this or at least automate pickling/unpickling variables in B?

解决方法:

关于硬解决方案

将包含要腌制的变量的字典添加到B:

Add to B a dictionary holding variables to pickle:

class B(A):
    __picklableObjects__ = {'_a0', '_a1', ... ,'_a101'}

    def __init__(self):
        #creates many object variables here
        A.__init__(self)
        self._a0 = ...
        ...
        self._a101 = ...

    @staticmethod
    def getPicklableObjects():
        return B.__picklableObjects__

    def __setstate__(self,state):
        A.__setstate__(self,state)
        for po in B.getPicklableObjects():
           __dict__[po] = state[po]

    def __getstate__(self):
        state = A.__getstate__(self)
        for po in B.getPicklableObjects():
            state[po] = copy.deepcopy(__dict__[po])
        return state

还有其他想法吗?

A的库:

好吧,对于您感兴趣的任何人A都是graph_tool.Graph: 一个src代码

Ok so for any of you interested A is graph_tool.Graph: A src code

line 786: class Graph(object)

...

line 1517: __getstate__

...

line 1533: __setstate__

推荐答案

根据文档,当未定义__getstate__时,将对实例的__dict__进行腌制,因此,也许可以使用它来定义自己的状态方法与A方法和实例的__dict__:

According to the documentation, when __getstate__ isn't defined, the instance's __dict__ is pickled so maybe, you can use this to define your own state methods as a combination of the A methods and the instance's __dict__:

import pickle

class A(object):
    def __init__(self):
        self.a = 'A state'

    def __getstate__(self):
        return {'a': self.a}

    def __setstate__(self, state):
        self.a = state['a']

class B(A):
    def __init__(self):
        A.__init__(self)
        self.b = 'B state'

    def __getstate__(self):
        a_state = A.__getstate__(self)
        b_state = self.__dict__
        return (a_state, b_state)

    def __setstate__(self, state):
        a_state, b_state = state
        self.__dict__ = b_state
        A.__setstate__(self, a_state)

b = pickle.loads(pickle.dumps(B()))
print b.a
print b.b

这篇关于如何腌制从A继承的B类(具有许多变量)的对象,该对象定义了__setstate__和__getstate__的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆