Python Notes: Reference and Dynamic Type

1,160 views

内容较水,让大牛们见笑了。Python语言采用所谓的“动态类型”,顺序执行如下三条语句是完全合法的:

>>> loli = 5
>>> loli = 3.142
>>> loli = "hello"

这种类型系统与静态类型的语言如C和Java等有很大不同。我认为比较容易理解的表述方式是:数据的类型与对象有关,与名字无关。变量名只是一个名字而已,它没有类型,可以理解成一个C语言里的(void*),类型信息是存储在变量指向的对象中。这个对象是内存中的一块区域,里面包含具体的值、这块对象的类型、引用计数等等信息。对于上面三条语句,可以理解为有一个叫做loli的变量,一开始指向一个整数对象,然后指向一个浮点数对象,最后指向一个字符串对象。

如前所述,Python变量表示的是对对象的“引用”,对象分为可变和不可变两种(这一点和Java类似),数值、字符串、tuple是不可变的,其余的是可变的。比如下面两条语句

>>> loli = 3
>>> roba = loli

首先loli指向一个整型对象(3),然后roba也指向同一个对象。Python有个id()函数,可以查看对象的内存地址,可以发现id(loli)和id(roba)是相同的。如果继续执行

>>> roba = roba + 1

则id(roba)可以发现指向的不同的位置。此时roba指向4,而loli仍指向3。因为整型对象是不可变的,所以roba必须指向一个新申请的叫做4的对象,而不能改变原来指向的那个3。与此相反,如果

>>> loli = [3]
>>> roba = loli
>>> roba[0] = roba[0] + 1
>>> loli
[4]
>>> roba
[4]

这里对象是可变的list,所以修改roba[0]的时候,loli指向的对象值也变了,因为它们始终指向同一个对象。如果我们想让他们指向不同的对象,则需调用copy.copy()进行复制。(关于copy和deepcopy的区别就以后再说吧)

在传递函数参数的时候也要注意这个问题,如果传的是不可变类型,在函数内部的修改不会影响到外面,如果是可变类型则有影响。

标签: ,

5 条评论 发表在“Python Notes: Reference and Dynamic Type”上

  1. Derek 说:

    roba = loli, 赞…

  2. hhb 说:

    roba=loli~

  3. Mgccl 说:

    有意思的变量名. python一般用spam,ham,egg.

  4. ant 说:

    roba likes loli ~~~

留下回复