如何挑选继承自A的B类(具有许多变量)的对象,该对象定义__setstate__和__getstate__

时间:2011-12-20 11:30:03

标签: python inheritance pickle

我的问题是:

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__方法,所以为了使泡菜能够起作用,我应该这样做:

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可以自行腌制(处理)的类型。 因此,如果B不从A继承,那么可能会有很好的结果:

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中的酸洗/去除变量吗?

变通方法解决方案:

至于硬解决方案

中的自动酸洗

将包含变量的字典添加到B中:

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的图书馆:

好的,对你们任何感兴趣的人都是graph_tool.Graph: A src code

line 786: class Graph(object)

...

line 1517: __getstate__

...

line 1533: __setstate__

2 个答案:

答案 0 :(得分:4)

根据文档,当未定义__getstate__时,实例的__dict__被腌制,所以也许,您可以使用它来定义您自己的状态方法作为{{1}的组合方法和实例的A

__dict__

答案 1 :(得分:0)

未定义Pickle的默认行为__getstate__是挑选对象__dict__属性的内容 - 这是存储实例属性的位置。

因此,在您的情况下,您需要做的就是让A获取并设置状态以保留self.__dict__中找到的值,然后在__setstate__恢复 - 这应该保留A的所有子类实例的实例变量。