Linux中国 Linux中国门户站!
设为主页 设为主页
收藏本站 收藏本站
 
当前位置 :首页 ->Linux技术 ->Linux程序设计 ->正文

Linux编程之序列化存储Python对象(上)

来源: 作者: 时间:2007-04-11 点击: [收藏] [投稿]

Pickle 的威力

到目前为止,我们讲述了关于 pickle 方面的基本知识。在这一节,把讨论一些高级问题,当您开始 pickle 复杂对象时,会遇到这些问题,其中包括定制类的实例。幸运的是,Python 可以很容易地处理这种情形。

可移植性

从空间和时间上说,Pickle 是可移植的。换句话说,pickle 文件格式独立于机器的体系结构,这意味着,例如,可以在 Linux 下创建一个 pickle,然后把它发送到在 Windows 或 Mac OS 下运行的 Python 程序。并且,当升级到更新版本的 Python 时,不必担心可能要废弃已有的 pickle。Python 开发人员已经保证 pickle 格式把可以向后兼容 Python 各个版本。事实上,在 pickle 模块中提供了有关目前以及所支持的格式方面的详细信息:

  >>> pickle.format_version
  '1.3'
  >>> pickle.compatible_formats
  ['1.0', '1.1', '1.2']
  

清单 3. 检索所支持的格式

多个引用,同一对象

在 Python 中,变量是对象的引用。同时,也可以用多个变量引用同一个对象。经证明,Python 在用经过 pickle 的对象维护这种行为方面丝毫没有困难,如清单 4 所示:

  >>> a = [1, 2, 3]
  >>> b = a
  >>> a
  [1, 2, 3]
  >>> b
  [1, 2, 3]
  >>> a.append(4)
  >>> a
  [1, 2, 3, 4]
  >>> b
  [1, 2, 3, 4]
  >>> c = pickle.dumps((a, b))
  >>> d, e = pickle.loads(c)
  >>> d
  [1, 2, 3, 4]
  >>> e
  [1, 2, 3, 4]
  >>> d.append(5)
  >>> d
  [1, 2, 3, 4, 5]
  >>> e
  [1, 2, 3, 4, 5]
  

清单 4. 对象引用的维护

循环引用和递归引用

可以把刚才演示过的对象引用支持扩展到循环引用(两个对象各自包含对对方的引用)和递归引用(一个对象包含对其自身的引用)。下面两个清单着重显示这种能力。我们先看一下递归引用:

  >>> l = [1, 2, 3]
  >>> l.append(l)
  >>> l
  [1, 2, 3, [...]]
  >>> l[3]
  [1, 2, 3, [...]]
  >>> l[3][3]
  [1, 2, 3, [...]]
  >>> p = pickle.dumps(l)
  >>> l2 = pickle.loads(p)
  >>> l2
  [1, 2, 3, [...]]
  >>> l2[3]
  [1, 2, 3, [...]]
  >>> l2[3][3]
  [1, 2, 3, [...]]
  

清单 5. 递归引用

现在,看一个循环引用的示例:

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

清单 6. 循环引用

注意,如果分别 pickle 每个对象,而不是在一个元组中一起 pickle 所有对象,会得到略微不同(但很重要)的结果,如清单 7 所示:

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

清单 7. 分别 pickle vs. 在一个元组中一起 pickle

()

 如果您对本文有任何疑问或者建议,请到讨论区发表您的意见: >> 论坛入口 <<



上一篇:Linux编程:把PHP作为Shell脚本使用   下一篇:Linux编程之序列化存储Python对象(下)

文章评论】 【收藏本文】 【推荐好友】 【打印本文】 【我要投稿】 【论坛讨论
更多相关文章
Power by linux-cn.com 粤ICP备05006655号