如何删除instancemethod对象,为了pickle,而不修改原始类

2024-06-17 18:05:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我想坚持保留reverend.thomas.Bayes中的一个对象。当然,如果我尝试直接抽取其中一个类,我会得到:

TypeError: can't pickle instancemethod objects

为了解决这个问题,我尝试声明两个函数:

^{pr2}$

基本上,我尝试复制对象的__dict__,并通过针对types.MethodType测试类型来删除{}。在

然后,我将通过创建一个新的Bayes对象,然后将其与bayes_dic合并(在取消拾取之后)

但是,我还没有找到第二个方法,因为我仍然不能在没有得到原始错误的情况下pickle从prepare_bayes_for_pickle返回的对象。在


Tags: 对象函数声明objectsthomascanpickledict
3条回答

更好的解决方案是将__getstate__方法添加到Bayes类中(并附带__setstate__):

import types
from reverend.thomas import Bayes

def Bayes__getstate__(self):
    state = {}
    for attr, value in self.__dict__.iteritems():
        if not isinstance(value, types.MethodType):
            state[attr] = value
        elif attr == 'combiner' and value.__name__ == 'robinson':
            # by default, self.combiner is set to self.robinson
            state['combiner'] = None
    return state

def Bayes__setstate__(self, state):
    self.__dict__.update(state)
    # support the default combiner (an instance method):
    if 'combiner' in state and state['combiner'] is None:
        self.combiner = self.robinson

Bayes.__getstate__ = Bayes__getstate__
Bayes.__setstate__ = Bayes__setstate__

现在,Bayes类总是可以被pickle和unpickle,而不需要额外的处理。在

我确实看到类有一个self.cache = {}映射;也许在pickle时应该排除它?在__getstate__中忽略它,并在__setstate__中调用self.buildCache()。在

k是一个键,即属性/方法名。您需要测试属性本身:

    if type(dic[k]) == types.MethodType:
            ^~~~~~ here

我更喜欢使用理解;您还应该使用isinstance

^{pr2}$

这听起来像是用一个方形的木桩来装圆孔。如何使用pickle来pickle参数,并取消pickle来重建reverand.Thomas.Bayes对象?在

>>> from collections import namedtuple
>>> ArgList = namedtuple('your', 'arguments', 'for', 'the', 'reverand')
>>> def pickle_rtb(n):
...     return pickle.dumps(ArgList(*n.args))
... 
>>> def unpickle_rtb(s):
...     return reverand.Thomas.Bayes(*pickle.loads(s))
... 
>>> s = pickle_rtb(reverand.Thomas.Bayes(1, 2, 3, 4, 5)) # note arguments are a guess
>>> rtb = unpickle_norm(s)

灵感来自于thisSO问题。在

相关问题 更多 >