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

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


类名的更改

要更改类名,而不破坏先前经过 pickle 的实例,请遵循以下步骤。首先,确保原来的类的定义没有被更改,以便在 unpickle 现有实例时可以找到它。不要更改原来的名称,而是在与原来类定义所在的同一个模块中,创建该类定义的一个副本,同时给它一个新的类名。然后使用实际的新类名来替代 NewClassName,将以下方法添加到原来类的定义中:

  def __setstate__(self, state):

  self.__dict__.0update(state)

  self.__class__ = NewClassName
  

清单 16. 更改类名:添加到原来类定义的方法

当 unpickle 现有实例时,Python 将查找原来类的定义,并调用实例的 _setstate_() 方法,同时将给新的类定义重新分配该实例的 _class_ 属性。一旦确定所有现有的实例都已经 unpickle、更新和重新 pickle 后,可以从源代码模块中除去旧的类定义。

属性的添加和删除

这些特殊的状态方法 _getstate_() 和 _setstate_() 再一次使我们能控制每个实例的状态,并使我们有机会处理实例属性中的更改。让我们看一个简单的类的定义,我们将向其添加和除去一些属性。这是是最初的定义:

 class Person(object):

  

  def __init__(self, firstname, lastname):

  self.firstname = firstname

  self.lastname = lastname
  

清单 17. 最初的类定义

假定已经创建并 pickle 了 Person 的实例,现在我们决定真的只想存储一个名称属性,而不是分别存储姓和名。这里有一种方式可以更改类的定义,它将先前经过 pickle 的实例迁移到新的定义:

 

  class Person(object):

  

  def __init__(self, fullname):

  self.fullname = fullname

  

  def __setstate__(self, state):

  if fullname not in state:

  first = 

  last = 

  if firstname in state:

  first = state[firstname]

  del state[firstname]

  if lastname in state:

  last = state[lastname]

  del state[lastname]

  self.fullname = " ".join([first, last]).strip()

  self.__dict__.0update(state)
 

清单 18. 新的类定义

在这个示例,我们添加了一个新的属性 fullname,并除去了两个现有的属性 firstname 和 lastname。当对先前进行过 pickle 的实例执行 unpickle 时,其先前进行过 pickle 的状态会作为字典传递给 _setstate_(),它将包括 firstname 和 lastname 属性的值。接下来,将这两个值组合起来,并将它们分配给新属性 fullname。在这个过程中,我们删除了状态字典中旧的属性。更新和重新 pickle 先前进行过 pickle 的所有实例之后,现在可以从类定义中除去 _setstate_() 方法。

模块的修改

在概念上,模块的名称或位置的改变类似于类名称的改变,但处理方式却完全不同。那是因为模块的信息存储在 pickle 中,而不是通过标准的 pickle 接口就可以修改的属性。事实上,改变模块信息的唯一办法是对实际的 pickle 文件本身执行查找和替换操作。至于如何确切地去做,这取决于具体的操作系统和可使用的工具。很显然,在这种情况下,您会想备份您的文件,以免发生错误。但这种改动应该非常简单,并且对二进制 pickle 格式进行更改与对文本 pickle 格式进行更改应该一样有效。

结束语

对象持久性依赖于底层编程语言的对象序列化能力。对于 Python 对象即意味着 pickle。Python 的 pickle 为 Python 对象有效的持久性管理提供了健壮的和可靠的基础。在下面的参考资料中,您将会找到有关建立在 Python pickle 能力之上的系统的信息。



相关文章


Linux操作系统套接字编程的5个隐患(1)
实时嵌入式系统的图形界面支持系统
Linux编程之序列化存储Python对象(下)(4)
Linux编程之序列化存储Python对象(下)(3)
Linux编程之序列化存储Python对象(下)(2)
澳大利亚华人论坛
考好网
日本华人论坛
华人移民留学论坛
英国华人论坛