3. 数据模型 | 您所在的位置:网站首页 › python中对象的三要素 › 3. 数据模型 |
3. 数据模型¶
3.1. 对象、值与类型¶
对象 是 Python 中对数据的抽象。 Python 程序中的所有数据都是由对象或对象间关系来表示的。 (从某种意义上说,按照冯·诺依曼的“存储程序计算机”模型,代码本身也是由对象来表示的。) 每个对象都有相应的标识号、类型和值。 一个对象被创建后它的 标识号 就绝不会改变;你可以将其理解为该对象在内存中的地址。 is 运算符比较两个对象的标识号是否相同;id() 函数返回一个代表其标识号的整数。 CPython 实现细节: 在 CPython 中,id(x) 就是存放 x 的内存的地址。 对象的类型决定该对象所支持的操作 (例如 "对象是否有长度属性?") 并且定义了该类型的对象可能的取值。type() 函数能返回一个对象的类型 (类型本身也是对象)。与编号一样,一个对象的 类型 也是不可改变的。[1] 有些对象的 值 可以改变。值可以改变的对象被称为 可变对象;值不可以改变的对象就被称为 不可变对象。(一个不可变容器对象如果包含对可变对象的引用,当后者的值改变时,前者的值也会改变;但是该容器仍属于不可变对象,因为它所包含的对象集是不会改变的。因此,不可变并不严格等同于值不能改变,实际含义要更微妙。) 一个对象的可变性是由其类型决定的;例如,数字、字符串和元组是不可变的,而字典和列表是可变的。 对象绝不会被显式地销毁;然而,当无法访问时它们可能会被作为垃圾回收。允许具体的实现推迟垃圾回收或完全省略此机制 --- 如何实现垃圾回收是实现的质量问题,只要可访问的对象不会被回收即可。 CPython 实现细节: CPython 目前使用带有 (可选) 延迟检测循环链接垃圾的引用计数方案,会在对象不可访问时立即回收其中的大部分,但不保证回收包含循环引用的垃圾。请查看 gc 模块的文档了解如何控制循环垃圾的收集相关信息。其他实现会有不同的行为方式,CPython 现有方式也可能改变。不要依赖不可访问对象的立即终结机制 (所以你应当总是显式地关闭文件)。 注意:使用实现的跟踪或调试功能可能令正常情况下会被回收的对象继续存活。还要注意通过 try...except 语句捕捉异常也可能令对象保持存活。 有些对象包含对“外部”资源如打开的文件或窗口的引用。 当对象被作为垃圾回收时这些资源也应该会被释放,但由于垃圾回收并不确保发生,这些对象还提供了明确地释放外部资源的操作,通常为一个 close() 方法。 强烈推荐在程序中显式关闭此类对象。 try...finally 语句和 with 语句提供了进行此种操作的更便捷方式。 有些对象包含对其他对象的引用;它们被称为 容器。容器的例子有元组、列表和字典等。这些引用是容器对象值的组成部分。在多数情况下,当谈论一个容器的值时,我们是指所包含对象的值而不是其编号;但是,当我们谈论一个容器的可变性时,则仅指其直接包含的对象的编号。因此,如果一个不可变容器 (例如元组) 包含对一个可变对象的引用,则当该可变对象被改变时容器的值也会改变。 类型会影响对象行为的几乎所有方面。甚至对象编号的重要性也在某种程度上受到影响: 对于不可变类型,会得出新值的运算实际上会返回对相同类型和取值的任一现有对象的引用,而对于可变类型来说这是不允许的。例如在 a = 1; b = 1 之后,a 和 b 可能会也可能不会指向同一个值为一的对象,这取决于具体实现,但是在 c = []; d = [] 之后,c 和 d 保证会指向两个不同、单独的新建空列表。(请注意 c = d = [] 则是将同一个对象赋值给 c 和 d。) 3.2. 标准类型层级结构¶以下是 Python 内置类型的列表。扩展模块 (具体实现会以 C, Java 或其他语言编写) 可以定义更多的类型。未来版本的 Python 可能会加入更多的类型 (例如有理数、高效存储的整型数组等等),不过新增类型往往都是通过标准库来提供的。 以下部分类型的描述中包含有 '特殊属性列表' 段落。这些属性提供对具体实现的访问而非通常使用。它们的定义在未来可能会改变。 3.2.1. None¶此类型只有一种取值。是一个具有此值的单独对象。此对象通过内置名称 None 访问。在许多情况下它被用来表示空值,例如未显式指明返回值的函数将返回 None。它的逻辑值为假。 3.2.2. NotImplemented¶此类型只有一种取值。 是一个具有该值的单独对象。 此对象通过内置名称 NotImplemented 访问。 数值方法和丰富比较方法如未实现指定运算符表示的运算则应返回该值。 (解释器会根据具体运算符继续尝试反向运算或其他回退操作。) 它不应被解读为布尔值。 详情参见 实现算术运算。 在 3.9 版本发生变更: 在布尔上下文件中对 NotImplemented 求值的操作已被弃用。 虽然它目前会被求解为真值,但将同时发出 DeprecationWarning。 它将在未来的 Python 版本中引发 TypeError。 3.2.3. Ellipsis¶此类型只有一种取值。是一个具有此值的单独对象。此对象通过字面值 ... 或内置名称 Ellipsis 访问。它的逻辑值为真。 3.2.4. numbers.Number¶此类对象由数字字面值创建,并会被作为算术运算符和算术内置函数的返回结果。数字对象是不可变的;一旦创建其值就不再改变。Python 中的数字当然非常类似数学中的数字,但也受限于计算机中的数字表示方法。 数字类的字符串表示形式,由 __repr__() 和 __str__() 算出,具有以下特征属性: 它们是有效的数字字面值,当被传给它们的类构造器时,将会产生具有原数字值的对象。 表示形式会在可能的情况下采用 10 进制。 开头的零,除小数点前可能存在的单个零之外,将不会被显示。 末尾的零,除小数点后可能存在的单个零之外,将不会被显示。 正负号仅在当数字为负值时会被显示。 Python 区分整型数、浮点型数和复数: 3.2.4.1. numbers.Integral¶此类对象表示数学中整数集合的成员 (包括正数和负数)。 备注 整型数表示规则的目的是在涉及负整型数的变换和掩码运算时提供最为合理的解释。 整型数可细分为两种类型: 整型 (int)此类对象表示任意大小的数字,仅受限于可用的内存 (包括虚拟内存)。在变换和掩码运算中会以二进制表示,负数会以 2 的补码表示,看起来像是符号位向左延伸补满空位。 布尔型 (bool)此类对象表示逻辑值 False 和 True。代表 False 和 True 值的两个对象是唯二的布尔对象。布尔类型是整型的子类型,两个布尔值在各种场合的行为分别类似于数值 0 和 1,例外情况只有在转换为字符串时分别返回字符串 "False" 或 "True"。 3.2.4.2. numbers.Real (float)¶此类对象表示机器级的双精度浮点数。其所接受的取值范围和溢出处理将受制于底层的机器架构 (以及 C 或 Java 实现)。Python 不支持单精度浮点数;支持后者通常的理由是节省处理器和内存消耗,但这点节省相对于在 Python 中使用对象的开销来说太过微不足道,因此没有理由包含两种浮点数而令该语言变得复杂。 3.2.4.3. numbers.Complex (complex)¶此类对象以一对机器级的双精度浮点数来表示复数值。有关浮点数的附带规则对其同样有效。一个复数值 z 的实部和虚部可通过只读属性 z.real 和 z.imag 来获取。 3.2.5. 序列¶这些代表以非负数为索引的有限有序集合。 内置函数 len() 将返回序列的项数。 当序列 的长度为 n 时,索引集合将包含数字 0, 1, ..., n-1。 a[i] 是选择序列 a 中的第 i 项。 某些序列,包括内置的序列,可通过加上序列长度来解读负下标值。 例如,a[-2] 等价于 a[n-2],即长度为 n 的 a 序列的倒数第二项。 序列还支持切片: a[i:j] 是选择索引为 k 使得 i |
CopyRight 2018-2019 实验室设备网 版权所有 |