VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • Python3标准库:pickle对象串行化(2)

  • data = []
  • data.append(SimpleObject('pickle'))
  • data.append(SimpleObject('preserve'))
  • data.append(SimpleObject('last'))
  •  
  • with open('Test.py', 'wb') as out_s:
  • for o in data:
  • print('WRITING: {} ({})'.format(
  • o.name, o.name_backwards))
  • pickle.dump(o, out_s)
  • 运行这个脚本时,会根据作为命令行参数给定的名字来创建一个文件。

    通过简单的尝试加载而得到的pickled对象将会失败。 

    
    	
    1. import pickle
    2.  
    3. with open('Test.py', 'rb') as in_s:
    4. while True:
    5. try:
    6. o = pickle.load(in_s)
    7. except EOFError:
    8. break
    9. else:
    10. print('READ: {} ({})'.format(
    11. o.name, o.name_backwards))

    这个版本失败的原因在于并没有SimpleObject类。

    修正后的版本从原脚本导入了SimpleObject,这一次运行会成功。在导入列表的最后增加了import语句后,现在脚本就能找到这个类并构造对象了。 

    
    	
    1. from demo import SimpleObject

    现在允许修改后的脚本会生成期望的结果。

    1.4 Unpicklable的对象 

    并不是所有对象都是可pickled的。套接字、文件句柄、数据库连接以及其他运行时状态依赖于操作系统或其他进程的对象,其可能无法用一种有意义的方式保存。如果对象包含不可pickled的属性,则可以定义__getstate__()和__setstate__()来返回所pickled实例的状态的一个子集。

    __getstate__()方法必须返回一个对象,其中包含所pickled对象的内部状态。表示状态的一种便利方式是使用字典,不过值可以是任意的可pickled对象。保存状态,然后再从pickle加载对象时将所保存的状态传入__setstate__()。

    
    	
    1. import pickle
    2.  
    3. class State:
    4.  
    5. def __init__(self, name):
    6. self.name = name
    7.  
    8. def __repr__(self):
    9. return 'State({!r})'.format(self.__dict__)
    10.  
    11. class MyClass:
    12.  
    13. def __init__(self, name):
    14. print('MyClass.__init__({})'.format(name))
    15. self._set_name(name)
    16.  
    17. def _set_name(self, name):
    18. self.name = name
    19. self.computed = name[::-1]
    20.  
    21. def __repr__(self):
    22. return 'MyClass({!r}) (computed={!r})'.format(
    23. self.name, self.computed)
    24.  
    25. def __getstate__(self):
    26. state = State(self.name)
    27. print('__getstate__ -> {!r}'.format(state))
    28. return state
    29.  
    30. def __setstate__(self, state):
    31. print('__setstate__({!r})'.format(state))
    32. self._set_name(state.name)
    33.  
    34. inst = MyClass('name here')
    35. print('Before:', inst)
    36.  
    37. dumped = pickle.dumps(inst)
    38.  
    39. reloaded = pickle.loads(dumped)
    40. print('After:', reloaded)

    这个例子使用了一个单独的State对象来保存MyClass的内部状态。从pickle加载MyClass的一个实例时,会向__setstate__()传入一个State实例,用来初始化这个对象。

    1.5 循环引用

    pickle协议会自动处理对象之间的循环引用,所以复杂数据结构不需要任何特殊的处理。 

    
    	
    1. import pickle
    2.  
    3. class Node:
    4. """A simple digraph
    5. """
    6. def __init__(self, name):
    7. self.name = name
    8. self.connections = []
    9.  
    10. def add_edge(self, node):
    11. "Create an edge between this node and the other."
    12. self.connections.append(node)
    13.  
    14. def __iter__(self):
    15. return iter(self.connections)
    16.  
    
    相关教程