9.1 持久化、类、状态以及数据表示
Python对象主要保存在计算机内存中,它们的生命周期就是Python进程。它们的生命周期甚至没有那么长,也许只是与它们在命名空间中的引用长短一致。如果希望一个对象的生命周期超过Python进程或命名空间,我们需要将它持久化。
大部分操作系统以文件系统的方式来提供持久化存储服务。这通常包括磁盘驱动器、闪存或其他稳定的存储形式。这只是将字节从内存中取出并存入磁盘文件的方式。
当内存中的Python对象引用了其他对象时,复杂度就增加了。一个对象引用了它自身的类,这个类引用了它的元类和其他基本类。这个对象可以是一个容器并且引用了其他对象。这个对象在内存中的版本就是包含一系列引用的关系网络。因为内存寻址是不固定的,如果没有将地址重写为独立于寻址方式的键值就试图从内存取出字节,这将破坏所保存的引用关系。所保存的引用关系大部分是静态的——例如类定义,相比于变量来说,变化非常少。理想情况下,一个类定义是不会改变的。然而,可能会出现类级别的实例变量。更重要的是,它改变了对象的功能。这个问题称为模型迁移问题,用于管理数据模型(或类)的变化。
一个对象的实例变量和类的属性在Python中有很正式的差别。我们的设计需要考虑到这些区别。当需要展示对象的动态状态时,需要定义一个对象的实例变量。而类中对象需要共享的信息会有选择地定义类级别的属性。如果我们可以只保存对象的动态状态——与类和类定义所包含的引用关系区分开——这就需要序列化和持久化的方案。
当保存类定义时,不必什么都做。我们已经将定义与其他部分完全分离了,并且所用的方法很简单。类定义主要以源代码形式存在。类定义在每次需要的时候被重新从源代码(或字节码)中取出,创建在内存中。如果需要交换类定义,也要交换Python的模块或包。
Python常用的术语
Python的常用术语主要是与dump和load有关的。在所定义的大多数类中会包含如下几种方法。
- dump(object , file):用于将对象转储到一个指定文件中。
- dump(object):返回一个对象的字符串表示。
- load(file):从指定文件中加载一个对象,返回新构造的对象。
- loads(string):从一个字符串加载一个对象,返回构造的对象。
这里并没有固定的规则,在任何正式的ABC继承或是mixin类定义中都并没有限制方法名称的使用。然而,它们仍然被广泛使用。通常情况下,用于转储或加载的文件可以是任何类似于文件的对象。可以使用read()和readline()这样的一些方法来实现加载,但我们需要的比这些还要多。因此,可使用io.StringIO对象和urllib.request对象作为加载的数据源。类似地,转储方面也对数据源有一定要求,接下来会对这些文件对象进行讨论。
