Differences between revisions 1 and 2
Revision 1 as of 2007-03-26 05:04:17
Size: 3084
Editor: HuangYi
Comment: Python 大统一理论
Revision 2 as of 2007-04-12 06:47:40
Size: 3521
Editor: HuangYi
Comment:
Deletions are marked like this. Additions are marked like this.
Line 8: Line 8:
而变量与对象之间的关系也都只有一种,那就是引用(c程序员来说是指针)!不过鉴于变量、引用这些词语的意义在历史潮流中已变得晦涩不清,在 python 中我们换几个术语,我们把变量叫做*名字*,把变量与对象之间的关系叫做*绑定*。名字与绑定这两个词语能够更准确得表达出 python (乃至所有动态语言)的特点。因为这里的名字确实就只是单纯的名字而已,它没有类型,也没有更多其他的意义。我们可以把名字绑定到任意的对象,也可以随时绑定到另一个对象。 而变量与对象之间的关系也都只有一种,那就是引用(c程序员可以把它简单地理解为指针)!不过鉴于变量、引用这些词语的意义在历史潮流中已变得晦涩不清,在 python 中我们换几个术语,我们把变量叫做*名字*,把变量与对象之间的关系叫做*绑定*。名字与绑定这两个词语能够更准确得表达出 python 的特点,在这里,名字就只是单纯的名字而已,它没有类型,也没有更多其他的意义。我们可以把名字绑定到任意的对象,也可以随时改变主意,让它绑定到另外的对象。
Line 10: Line 10:
程序员总是通过名字间接操纵对象

而没有名字的对象那是内存泄露了 ;-)
程序员总是通过名字对对象进行操纵。而没有名字的对象那肯定是内存泄露了,不过不用担心,Python 会自动回收掉那些没有名字的家伙 ;-)
Line 48: Line 46:
介绍完名字与对象的关系,我们要开始介绍 python 对名字的管理,就是*名字空间* 介绍完名字与对象的关系,我们要开始介绍 python 对名字的管理就是所谓的*名字空间*。
Line 50: Line 48:
python 程序中所有的名字都存在于某一个名字空间中。对于一个普通 python 函数来说,只存在着三层嵌套的名字空间,即局部名字空间、全局名字空间、内置名字空间。不过对于嵌套函数或是嵌套类来说,就不止三层了,每一层嵌套都是多一层名字空间 python 程序中任何一个名字都存在于某一个名字空间中。对于一个普通 python 函数来说,只存在着三层嵌套的名字空间,即局部名字空间、全局名字空间、内置名字空间。不过对于嵌套函数或是嵌套类来说,就不止三层了,每一层嵌套都是多一层名字空间,例如:
Line 52: Line 50:
对一个名字的查找过程总是由内而外的,除非你用 global 关键字显式指定某个名字存在于全局名字空间。 当读取一个名字——即通过名字获取其绑定的对象——时,默认总是从当前名字空间开始向外对名字进行查找。不过使用 global 关键字可以显式指明该名字存在于全局名字空间,就可以免去查找的过程了。
Line 54: Line 52:
其实当我们把视野放大,把程序看作是一个一个的模块,就会发现所谓全局名字空间其实并不是全局的,而只是模块级的,所以我们也常把它叫做模块级名字空间。内置名字空间才是真正是全局的名字空间。 不过重新绑定一个名字时,默认情况下却只在当前名字空间中找,这可以有效地避免对外部名字空间的污染和程序发生一些意象不到的行为。(Python3000)
Line 56: Line 54:
== 类型 == 其实当我们把视野放大,把程序看作是一个个的模块,就会发现所谓全局名字空间其实并不是全局的,而只是模块级的,所以我们也常把它叫做模块级名字空间。内置名字空间才是真正是全局的名字空间。

== 类型与对象 ==

TableOfContents

Python 大统一理论

对象 名字与绑定

python 中有一条不成文的定律,那就是*万物皆对象*!不光是大家熟悉的实例对象是对象,连类、模块、包这些,甚至包括基本的数值类型,都被一视同仁,当作对象看待。不再有值类型与引用类型的区别,也不再需要什么 boxing/unboxing 的操作。

而变量与对象之间的关系也都只有一种,那就是引用(c程序员可以把它简单地理解为指针)!不过鉴于变量、引用这些词语的意义在历史潮流中已变得晦涩不清,在 python 中我们换几个术语,我们把变量叫做*名字*,把变量与对象之间的关系叫做*绑定*。名字与绑定这两个词语能够更准确得表达出 python 的特点,在这里,名字就只是单纯的名字而已,它没有类型,也没有更多其他的意义。我们可以把名字绑定到任意的对象,也可以随时改变主意,让它绑定到另外的对象。

程序员总是通过名字对对象进行操纵。而没有名字的对象那肯定是内存泄露了,不过不用担心,Python 会自动回收掉那些没有名字的家伙 ;-)

现在传值还是传引用这个经典问题不复存在了,但 c程序员却要发问了:

   1 >>> a=1
   2 >>> b=a
   3 >>> a+=1
   4 >>> a
   5 2
   6 >>> b
   7 1

既然 a、b 两个名字绑定着同一个对象(整数1),那么当通过名字 a 修改(加1)了该对象之后,为何 b 所绑定的对象却还是 1 呢?

这就涉及到了 python 对象的两个派别:可变对象与不可变对象。不可变就是不可以修改的意思。对于任何修改不可变对象的意图,或者是抛出异常,或者就是返回一个新的对象。整数便是属于不可变对象这一派的。

   1 >>> a=b=1
   2 >>> a+=1
   3 >>> id(a)==id(b)
   4 False

由此可见,名字 a、b 所绑定的已不是同一个对象了。这一派的对象还包括:字符串(str)、元组(tuple) 等。

   1 >>> a=b='hello'
   2 >>> a[0]='a'
   3 Traceback (most recent call last):
   4   File "<stdin>", line 1, in ?
   5 TypeError: object does not support item assignment
   6 >>> a+='hello'
   7 >>> id(a)==id(b)
   8 False

名字空间

介绍完名字与对象的关系,我们要开始介绍 python 对名字的管理了,这就是所谓的*名字空间*。

python 程序中任何一个名字都存在于某一个名字空间之中。对于一个普通 python 函数来说,只存在着三层嵌套的名字空间,即局部名字空间、全局名字空间、内置名字空间。不过对于嵌套函数或是嵌套类来说,就不止三层了,每一层嵌套都是多一层名字空间,例如:

当读取一个名字——即通过名字获取其绑定的对象——时,默认总是从当前名字空间开始向外对名字进行查找。不过使用 global 关键字可以显式指明该名字存在于全局名字空间,就可以免去查找的过程了。

不过重新绑定一个名字时,默认情况下却只在当前名字空间中找,这可以有效地避免对外部名字空间的污染和程序发生一些意象不到的行为。(Python3000)

其实当我们把视野放大,把程序看作是一个个的模块,就会发现所谓全局名字空间其实并不是全局的,而只是模块级的,所以我们也常把它叫做模块级名字空间。内置名字空间才是真正是全局的名字空间。

类型与对象

GrandUnifiedTheory (last edited 2009-12-25 07:15:31 by localhost)