分段腌制对象与一次腌制对象之间的区别?
Difference between pickling an object piecewise vs all at once?
给定一个像这样的任意 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) )
我无法想象,但我担心可能有一些我没有考虑的极端情况。
(在我的应用程序中,某些对象可能没有可序列化的变量。我们希望实现分段酸洗,以便我们更好地识别哪些变量阻止我们对对象进行酸洗)
在第一种情况下,您将创建 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()
执行你的第一个代码后,returns 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
执行第二个代码后,returns ExampleObj
:
的一个实例
restored_2.foo() # bar
restored_2.bar # ab
restored_2.__dict__ # {'a': 'a', 'b': 'b', 'c': 'c'}
如果您正在寻找有关查看哪个实例 attrs pickling 失败的方法的讨论,请参阅此问题:How to tell for which object attribute pickle fails?
给定一个像这样的任意 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) )
我无法想象,但我担心可能有一些我没有考虑的极端情况。
(在我的应用程序中,某些对象可能没有可序列化的变量。我们希望实现分段酸洗,以便我们更好地识别哪些变量阻止我们对对象进行酸洗)
在第一种情况下,您将创建 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()
执行你的第一个代码后,returns 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
执行第二个代码后,returns ExampleObj
:
restored_2.foo() # bar
restored_2.bar # ab
restored_2.__dict__ # {'a': 'a', 'b': 'b', 'c': 'c'}
如果您正在寻找有关查看哪个实例 attrs pickling 失败的方法的讨论,请参阅此问题:How to tell for which object attribute pickle fails?