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

文章作者 100test 发表时间 2007:03:14 16:31:46
来源 100Test.Com百考试题网


类实例

与 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 模块,它包含以下新型类的定义:

  class Foo(object):

  

  def __init__(self, value):

  self.value = value
  

清单 11. 新型类的定义

现在可以 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

  Svalue

  p6

  SWhat is a Foo?

  sb.

  >>>
  

清单 12. pickle Foo 实例

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

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

  >>> 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
  

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

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

  >>> 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
  

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

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



相关文章


实时嵌入式系统的图形界面支持系统
Linux编程之序列化存储Python对象(下)(4)
Linux编程之序列化存储Python对象(下)(3)
Linux编程之序列化存储Python对象(下)(2)
Linux编程之序列化存储Python对象(下)(1)
让微软汗颜的XGL-Linux真正的3D桌面
澳大利亚华人论坛
考好网
日本华人论坛
华人移民留学论坛
英国华人论坛