文章目录
  1. 1. 概述
  2. 2. Python中一切皆对象
  3. 3. 对象
  4. 4. 对象扩展
  5. 5. 命名(names)
  6. 6. 赋值
  7. 7. 参考

概述

很多Python书籍和Python教程都会提到Python中一切皆对对象,但是这些教程往往不会深入解释这句话到底什么意思,这篇文章主要讨论下Python中一切皆对象这句话的深层含义。

Python中一切皆对象

Dive into Python这本书给了这句话一个很好的解释:

不同的编程语言使用不同的方式定义对象。在某些编程语言中,它意味着所有的对象都必须有方法和属性。在另外一些编程语言中,它意味着所有对象必须可子类化(subclassable)。在Python中,这个定义更松散,它并不需要所有的对象都有属性和方法,也不需要所有的对象都可以子类化。但是,在Python中一切皆对象意味着一切皆是对象,它可以被分配给一个变量,亦可以做为函数参数。

Python中,一切皆是对象,String是对象,Lists是对象,Functions是对象,甚至于Modules都是对象。

对象

在Python中,所有对象都有如下特点:

  • 一个唯一的ID (ID是一个整型数字,通过id(x)获得)
  • 一个类型 (通过 type(x)获得)
  • 一些内容

对象的ID不能修改。

对象的类型不能修改。

有些对象允许修改其内容(ID和类型永远不能被修改),这类对象称为可变对象(Mutable)。有些对象不允许修改其内容,这类对象称为不可变对象(Immutable)。

对象类型被一个类型对象(type object)所表示,该类型对象掌握更多该类型对象的信息,如对象占用了多少内存,对象拥有哪些方法。

在CPython 2.2 或者更新的版本中,在某些限制不严格的环境中,可以修改对象的类型。

对象扩展

在Python中,对象还可能有如下特点:

  • 0个或多个方法
  • 0个或多个名称

有些对象提供一些允许修改其内容的方法。有些对象仅提供一些允许访问其内容,但不允许修改的方法。有些对象则没有任何方法。

平时所用到的属性赋值和项引用,仅仅是一种语法糖

命名(names)

命名是指我们通常所说的变量名。

这里的命名有一点不同–名称并不是对象的属性,对象本身并不知道自己叫什么名称。

一个对象可以有许多个命名,也可以没有任何命名。

名称存在于命名空间中,如模块命名空间、实例命名空间、函数本地命名空间等。

命名空间是键值对(使用字典实现)的集合。

当我们调用一个函数时,函数的命名空间随着调用函数时传递的参数被初始化。

赋值

赋值操作改变的是命名空间,并没有修改对象。

如下示例:

1
name = 10

上述代码意味着将name这个名称添加到本地的命名空间中,同时将这个名称指向一个值为10的整型对象。

如果某个名称之前已经存在,赋值操作将替换原来的名称指向。 示例如下:

1
2
name = 10
name = 20

上述代码表示,首先将name这个名称添加到本地命名空间中,并将它指向一个值为10的整型对象中。然后,第二次赋值操作,替换了name这个名称的内容,将它指向一个值为20的整型对象中。最初的值为10的整型对象并未被该操作影响。

相反的,如果执行以下操作:

1
2
name = []
name.append(1)

上述代码中,首先将name这个名称添加到了本地命名空间中,并将它指向一个值列表对象中,这个操作修改了命名空间。然后,调用了该对象的一个方法,向自身添加一个整型对象,这个操作修改对象本身的内容,但是它并没有影响到命名空间,也没有影响到添加到自身的整型对象。

上述代码中,name.attrname[index]这些可能的操作仅仅是语法糖。如,name.attr对应__setattr__/__getattr__方法,name[index]对应__setitem__/__getitem__方法。

参考