以下代码正确运行:
import pickle
class MyClass():
def __init__(self, arg):
self.arg = arg
a = MyClass('my arg')
with open('/home/mahikeulbody/mypickle', 'wb') as file:
pickle.dump(a, file)
但是添加一个装饰器来获得一个多元类:
import pickle
def multiton(cls):
instances = {}
def getinstance(arg):
if arg not in instances:
instances[arg] = cls(arg)
return instances[arg]
return getinstance
@multiton
class MyClass():
def __init__(self, arg):
self.arg = arg
a = MyClass('my arg')
with open('/home/michel/mypickle', 'wb') as file:
pickle.dump(a, file)
产生以下错误:
pickle.dump(a, file)
_pickle.PicklingError: Can't pickle <class '__main__.MyClass'>: it's not the same object as __main__.MyClass
有什么问题?
答案 0 :(得分:2)
Pickle必须能够直接加载该类。你的装饰者用工厂函数替换类,这使得pickle无法导入类本身。
使用单独的工厂功能,而不是装饰器,返回私人&#39; class(但仍可直接导入):
class _MyClass():
def __init__(self, arg):
self.arg = arg
def MyClass(arg, instances={}):
if arg not in instances:
instances[arg] = _MyClass(arg)
return instances[arg]
答案 1 :(得分:0)
为此,我使用dill,它可以在python中序列化几乎任何东西。
>>> def multiton(cls):
... instances = {}
... def getinstance(arg):
... if arg not in instances:
... instances[arg] = cls(arg)
... return instances[arg]
... return getinstance
...
>>> @multiton
... class MyClass():
... def __init__(self, arg):
... self.arg = arg
...
>>> import dill
>>>
>>> a = MyClass('my arg')
>>> b = dill.loads(dill.dumps(a))
>>> a
<__main__.MyClass instance at 0x4d64558>
>>> b
<__main__.MyClass instance at 0x4d64800>
Dill还有some good tools帮助您了解代码失败时导致酸洗失败的原因。