首页 | Linux 基础 | 资讯动态 | Linux 应用 | Linux 服务器 | Linux 开发 | Linux 安全 | 专题 | 联盟论坛
  当前位置:主页>Linux 开发>文章内容
Linux编程之序列化存储Python对象(下)
来源:www.unix5.com 作者:riechelr_hl 发布时间:2007-06-05  

文章接<<Linux编程之序列化存储Python对象(上)>>之下篇讲解.

相等,但并不总是相同

正如在上一个示例所暗示的,只有在这些对象引用内存中同一个对象时,它们才是相同的。在 pickle 情形中,每个对象被恢复到一个与原来对象相等的对象,但不是同一个对象。换句话说,每个 pickle 都是原来对象的一个副本:

 

  >>> j = [1, 2, 3]
  >>> k = j
  >>> k is j
  1
  >>> x = pickle.dumps(k)
  >>> y = pickle.loads(x)
  >>> y
  [1, 2, 3]
  >>> y == k
  1
  >>> y is k
  0
  >>> y is j
  0
  >>> k is j
  1

  

 

清单 8. 作为原来对象副本的被恢复的对象

同时,我们看到 Python 能够维护对象之间的引用,这些对象是作为一个单元进行 pickle 的。然而,我们还看到分别调用 dump() 会使 Python 无法维护对在该单元外部进行 pickle 的对象的引用。相反,Python 复制了被引用对象,并把副本和被 pickle 的对象存储在一起。对于 pickle 和恢复单个对象层次结构的应用程序,这是没有问题的。但要意识到还有其它情形。

值得指出的是,有一个选项确实允许分别 pickle 对象,并维护相互之间的引用,只要这些对象都是 pickle 到同一文件即可。pickle 和 cPickle 模块提供了一个 Pickler(与此相对应是 Unpickler),它能够跟踪已经被 pickle 的对象。通过使用这个 Pickler,把会通过引用而不是通过值来 pickle 共享和循环引用:

 

  >>> f = file('temp.pkl', 'w')
  >>> pickler = pickle.Pickler(f)
  >>> pickler.dump(a)
  
  >>> pickler.dump(b)
  
  >>> f.close()
  >>> f = file('temp.pkl', 'r')
  >>> unpickler = pickle.Unpickler(f)
  >>> c = unpickler.load()
  >>> d = unpickler.load()
  >>> c[2]
  [3, 4, [1, 2, [...]]]
  >>> d[2]
  [1, 2, [3, 4, [...]]]
  >>> c[2] is d
  1
  >>> d[2] is c
  1

  

 

清单 9. 维护分别 pickle 的对象间的引用

不可 pickle 的对象

一些对象类型是不可 pickle 的。例如,Python 不能 pickle 文件对象(或者任何带有对文件对象引用的对象),因为 Python 在 unpickle 时不能保证它可以重建该文件的状态(另一个示例比较难懂,在这类文章中不值得提出来)。试图 pickle 文件对象会导致以下错误:

 

  >>> f = file('temp.pkl', 'w')
  >>> p = pickle.dumps(f)
  Traceback (most recent call last):
  File "", line 1, in ?
  File "/usr/lib/python2.2/copy_reg.py", line 57, in _reduce
  raise TypeError, "can't pickle %s objects" % base.__name__
  TypeError: can't pickle file objects

  

 

清单 10. 试图 pickle 文件对象的结果
类实例
与 pickle 简单对象类型相比,pickle 类实例要多加留意。这主要由于 Python 会 pickle 实例数据(通常是 _dict_ 属性)和类的名称,而不会 pickle 类的代码。当 Python unpickle 类的实例时,它会试图使用在 pickle 该实例时的确切的类名称和模块名称(包括任何包的路径前缀)导入包含该类定义的模块。另外要注意,类定义必须出现在模块的最顶层,这意味着它们不能是嵌套的类(在其它类或函数中定义的类)。
当 unpickle 类的实例时,通常不会再调用它们的 _init_() 方法。相反,Python 创建一个通用类实例,并应用已进行过 pickle 的实例属性,同时设置该实例的 _class_ 属性,使其指向原来的类。
共4页: 上一页 1 [2] [3] [4] 下一页
 
如果您对本文有任何疑问或者建议,请到论坛讨论区发表您的意见: >> 论坛入口
[收藏] [推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
  热点文章
·嵌入式Linux系统下图形库讲解及
·Qt/Embedded在嵌入式Linux中的应
·Linux系统环境下的Socket编程详
·在 Fedora Core 5 上体验 Aiglx
·使用 Linux 系统调用的内核命令
·Linux 2.6.11内核文件IO系统调用
·在Linux中创建静态库和动态库
·嵌入式Linux:uClinux操作系统移
·Linux操作系统下的多进程编程(
·嵌入式系统 Boot Loader 技术内
·Linux操作系统的源代码目录树结
·Linux用户态与内核态的交互讲解
  相关文章
·Shell基本工作原理方案
·Linux编程之序列化存储Python对
·Linux编程:把PHP作为Shell脚本
·Linux 操作系统编程之Shell 问答
·Linux 2.6 内核的嵌入式系统应用
·内核设计篇
·基于嵌入式Linux平台的多协议路
·两个很详细的shell实例
·嵌入式Linux在Blackfin处理器上
·精华:学习嵌入式Linux的笔记和
·嵌入式Linux:uClinux操作系统移
·Linux系统可卸载内核模块完全指

本站信息源至:互联网络,均为学习,交流所用,如有版权问题,请联系我们.
站长QQ:397422079 E_mail:riechelr_hl@unix5.com
转载本站内容请注明原作者名.谢谢!