给出这样的任意pythonic对象:
class ExampleObj(object):
def __init__(self):
self.a = 'a'
self.b = 'b'
self.c = 'c'
obj = ExampleObj()
这两种序列化方法之间是否存在功能差异?
片状酸洗
base = type(obj)
name = obj.__class__.__name__
pickled_data = {}
for key,val in obj.__dict__.items():
pickled_data[key] = pickle.dumps(val)
vars = {k : pickle.loads(v) for k,v in pickled_data.items()}
restored = type(name, (base,), vars)
标准酸洗
restored = pickle.loads( pickle.dumps(obj) )
我无法想象任何事情,但是我担心可能没有考虑一些极端情况。
(在我的应用程序中,某些对象可能没有可序列化的变量。我们希望实现分段酸洗,以便我们更好地识别哪些变量阻止我们酸洗对象)
答案 0 :(得分:1)
在第一种情况下,您正在创建type
的实例,而在第二种情况下,您正在创建类型为ExampleObj
的实例。要查看两个结果在功能上的不同,我将第一个示例的结果命名为restored_1
,第二个命名为restored_2
。
type(restored_1) # type
type(restored_2) # __main__.ExampleObj
因此,restored_1
和restored_2
在功能上不等同于您所要查找的内容。
为简单起见,请向ExampleObj
添加方法或属性,然后尝试以各种方式使用任一过程中的还原对象。
class ExampleObj(object):
def __init__(self):
self.a = 'a'
self.b = 'b'
self.c = 'c'
def foo(self):
print('bar')
@property
def baz(self):
print(self.a + self.b)
obj = ExampleObj()
执行您的第一个代码后,它返回type
的实例:
restored_1.foo() # exception raised because restored_1 is not an ExampleObj instance
restored_1.bar # returns <property at 0x107863138> type
restored_1.__dict__ # returns a mappingproxy object
执行完第二条代码后,该代码返回ExampleObj
的实例:
restored_2.foo() # bar
restored_2.bar # ab
restored_2.__dict__ # {'a': 'a', 'b': 'b', 'c': 'c'}
如果您正在寻找有关解决哪些实例attrs酸洗失败的方法的讨论,请参见以下问题:How to tell for which object attribute pickle fails?