Python学习笔记:对象,值和类型

来源:互联网 发布:reveal.js 幻灯片 编辑:程序博客网 时间:2024/04/29 07:49

本篇参考Python官方文档,3. Data model — Python 3.5.2 documentation

下面是原文翻译过来的:

对象 是Python对数据的抽象。Python程序程序中所有的数据都用对象或者对象之间的关系表示。(在某种意义上,与冯诺依曼的“程序存储计算机”模型相一致,代码也由对象表示)
每个对象都有一个身份(identity),类型和值。一个对象的身份从创建开始就不会改变。你可以吧它理解成内存中的一个地址。’is’操作符比较两个对象的身份,id()函数返回一个表示身份的整数。
一个对象的类型决定这个对象支持什么操作(比如,“它有长度吗?”),它还定义了这个类型所有可能的值。type()函数返回一个对象的类型(也就是对象本身)。像它的身份一样,一个对象的类型也不可改变(unchangeable)。
某些对象的可以改变。值可以改变的对象被称为可变的(mutable);值自创立起就不能改变的对象被称为不变的(immutable)。(一个不变的、含有一个可变对象的引用的容器对象(container)的值可以改变当后者的值被改变;然而这个容器仍然被视为不可变,因为它含有的集合对象不能被改变。所以,不可变性不是严格地跟有一个不能被改变的值一样,不可变性更微妙。)一个对象的可变性由它的类型决定;比如,数字,字符串和元组是不可变的,字典和链表是可变的。
对象从不是被显式的销毁。然而,当它们变得不能接触(unreachable)它们可能被当做垃圾回收。

这几段定义了对象,身份,类型和值。其中还没有说明白,可以理解为内存块实际包含的信息。还有个概念这里没提到,就是标识符(identifier),在Python里,标识符跟名字(name)是同义词。同样在Python里,标识符和引用是孪生兄弟。在Python中提到引用或者标识符的时候,就马上联想到“这只不过是给对象起了个名字而已”。再次强调一下,Python中的概念一定要从Python官方给的定义出发,万不可简单类比其他语言。
下面打个比方描述一下这些概念,把内存比作仓库,仓库分成一个个储物柜,每个储物柜就是一个内存块。每个储物柜都有一个唯一的不能更改的编号。每当创建一个新的对象,就为这个对象分配一个储物柜,储物柜的编号就是这个对象的身份,比如8号。对象的值就是放在储物柜里的东西。如果这个对象是mutable,那么它的柜子里的东西就可以更改,反之则不能更改。你可以给这个新创建的对象起个名字,比如老大,老二,铁柱。
这里要着重解释的概念是mutable和immutable。注意到没有用changeable,所以mutable不能简单地翻译成“可改变的”,我姑且翻译成”可变的“,但是准确起见还是直接用英文。上面括号里有一段话我翻译的很生硬,原文是:

The value of an immutable container object that contains a reference to a mutable object can change when the latter’s value is changed; however the container is still considered immutable, because the collection of objects it contains cannot be changed. So, immutability is not strictly the same as having an unchangeable value, it is more subtle.

这段话解释了mutable和changeable之间的微妙差别。如果有一个immutable对象(可以把这个对象叫老大),这个对象很特别,因为它的值是另一个可变对象的引用(把这个对象叫小二)。即,名字叫做老大的对象的储物柜里的东西不能改变,这个东西是“小二”,小二是另一个可变对象的名字。当我们说“把666给老大”的时候,这句话是可行的。表面上看起来我们好像改变了老大的值,那么老大到底是不是可改变的呢?微妙的地方就在这里,实际上我们并没有改变老大的值,我们改变的是老大的值的值。为了严格区分开这个歧义,changeble是口语上的,宽泛意义上的可改变;mutable是数学上的可变,只形容值可以改变的对象。
看文档里还有一段补充说明:

有些对象包含其他对象的引用,这些对象叫做容器(container),比如元组,链表和字典。引用是容器的值得一部分。大多数情况下,当我们说容器的值的时候,我们指的是值的值,而不是容器包含的标识符。然而,当我们谈论一个容器的mutability,我们衡量的只是这个容器包含的其他对象的标识符。所以,如果一个immutable容器包含一个mutable对象的引用,如果这个mutable对象变了,那么这个容器的值变了。

0 0