中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档 | 网通镜像
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > 综合其它
LINUX应用技巧,序列化存储 Python 对象(3)
作者:佚名 时间:2007-09-18 16:33 出处:ibm 责编:月夜寒箫
              摘要:LINUX应用技巧,序列化存储 Python 对象(3)
不可 pickle 的对象

 

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

清单 10. 试图 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

类实例

与 pickle 简单对象类型相比,pickle 类实例要多加留意。这主要由于 Python 会 pickle 实例数据(通常是 _dict_ 属性)和类的名称,而不会 pickle 类的代码。当 Python unpickle 类的实例时,它会试图使用在 pickle 该实例时的确切的类名称和模块名称(包括任何包的路径前缀)导入包含该类定义的模块。另外要注意,类定义必须出现在模块的最顶层,这意味着它们不能是嵌套的类(在其它类或函数中定义的类)。

当 unpickle 类的实例时,通常不会再调用它们的 _init_() 方法。相反,Python 创建一个通用类实例,并应用已进行过 pickle 的实例属性,同时设置该实例的 _class_ 属性,使其指向原来的类。

对 Python 2.2 中引入的新型类进行 unpickle 的机制与原来的略有不同。虽然处理的结果实际上与对旧型类处理的结果相同,但 Python 使用 copy_reg 模块的 _reconstructor() 函数来恢复新型类的实例。

如果希望对新型或旧型类的实例修改缺省的 pickle 行为,则可以定义特殊的类的方法 _getstate_() 和 _setstate_(),在保存和恢复类实例的状态信息期间,Python 会调用这些方法。在以下几节中,我们会看到一些示例利用了这些特殊的方法。

现在,我们看一个简单的类实例。首先,创建一个 persist.py 的 Python 模块,它包含以下新型类的定义:

清单 11. 新型类的定义

class Foo(object):

def __init__(self, value):

self.value = value

现在可以 pickle Foo 实例,并看一下它的表示:

清单 12. pickle Foo 实例

>>> import cPickle as pickle

>>> from Orbtech.examples.persist import Foo

>>> foo = Foo('What is a Foo?')

>>> p = pickle.dumps(foo)

>>> print p

ccopy_reg

_reconstructor

p1

(cOrbtech.examples.persist

Foo

p2

c__builtin__

object

p3

NtRp4

(dp5

S'value'

p6

S'What is a Foo?'

sb.

>>>

可以看到这个类的名称 Foo 和全限定的模块名称 Orbtech.examples.persist 都存储在 pickle 中。如果将这个实例 pickle 成一个文件,稍后再 unpickle 它或在另一台机器上 unpickle,则 Python 会试图导入 Orbtech.examples.persist 模块,如果不能导入,则会抛出异常。如果重命名该类和该模块或者将该模块移到另一个目录,则也会发生类似的错误。

这里有一个 Python 发出错误消息的示例,当我们重命名 Foo 类,然后试图装入先前进行过 pickle 的 Foo 实例时会发生该错误:

清单 13. 试图装入一个被重命名的 Foo 类的经过 pickle 的实例

>>> import cPickle as pickle

>>> f = file('temp.pkl', 'r')

>>> foo = pickle.load(f)

Traceback (most recent call last):

File "", line 1, in ?

AttributeError: 'module' object has no attribute 'Foo'

在重命名 persist.py 模块之后,也会发生类似的错误:

清单 14. 试图装入一个被重命名的 persist.py 模块的经过 pickle 的实例

>>> import cPickle as pickle

>>> f = file('temp.pkl', 'r')

>>> foo = pickle.load(f)

Traceback (most recent call last):

File "", line 1, in ?

ImportError: No module named persist

我们会在下面模式改进这一节提供一些技术来管理这类更改,而不会破坏现有的 pickle。

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有