2018-06-20

大连

/python/2018/06/20/object.html

python

python

本文最近更新于 2018 年 07 月 05 日Python 是一门优雅而健壮的编程语言,它继承了传统编译语言的强大性和通用性,同时也借鉴了简单脚本和解释语言的易用性。


在 Python 中有一句话——一切皆对象。那应该如何理解“一切皆对象”?

何为对象?

不同的编程语言以不同的方式定义“对象”。某些语言中,它意味着所有对象必须有属性和方法;另一些语言中,它意味着所有的对象都可以子类化。在 Python 中,定义是松散的,某些对象既没有属性也没有方法,而且不是所有的对象都可以子类化。但是 Python 的万物皆对象从感性上可以解释为:Python 中的一切都可以赋值给变量或者作为参数传递给函数。

在 The Python Language Referenceis 操作符比较两个对象的 ID;id() 函数返回一个表示对象 ID 的整数。对象的类型决定对象能够支持的操作(例如,它是否具有长度?),还定义该类型的对象可能有的值/取值范围。type() 函数返回对象的类型(它本身也是一个对象)。与 ID 一样,对象的类型也是不可以修改的。

解释

“一切皆对象”也就是说在 Python 中下列语句其实都有一个共同点:i = 1

s = "abc"

def foo(): pass

class C(object): pass

instance = C()

l = [1, 2, 3]

t = (1, 2, 3)

它们在 Python 解释器中执行的时候,都会在堆中新建了一个对象,然后把新建的对象绑定到变量名上:i = 1 #新建一个 PyIntObject 对象,绑定到 i 上

s = "abc" #新建一个 PyStringObject 对象,绑定到 s 上

def foo(): pass #新建一个 PyFunctionObject 对象,绑定到 foo 上

class C(object): pass #新建一个类对象,绑定到 C 上

instance = C() #新建一个实例对象,绑定到 instance 上

l = [1, 2, 3] #新建一个 PyListObject 对象,绑定到 l 上

t = (1, 2, 3) #新建一个 PyTupleObject 对象,绑定到 t 上

分析

每个对象都有一个唯一的身份标识自己,可以使用内建函数 id() 来得到,我们可以把这个值理解为该对象的内存地址:>>> i = 1

>>> id(i)

8104016

>>>

对象的类型决定了对象可以用来保存什么类型的值,有哪些属性和方法,可以进行哪些操作,遵循怎样的规则。可以使用内建函数 type() 来查看对象的类型(代码续上):>>> type(i)

>>> type(type)

#type 也是一种特殊的对象 type

>>> i

1

>>>

“身份标识(ID)”、“类型”和“值”随对象被创建而产生。如果对象支持更新操作,则它的值是可变的,否则为只读(数字、字符串、元组等均不可变)。只要对象还存在,这三个特性就一直存在。

所以,简单来看,i = 1 是将变量 i 和数字 3 进行连接,使 i 成为对象 3 的一个引用(可以理解为变量是到对象的内存空间的一个指针),需要注意的是:变量总是连接到对象,而不会连接到其他变量。

从概念上可以这样理解:对象是堆上分配的一个内存空间,用来表示对象所代表的值;变量是一个系统创建的元素,拥有指向对象的引用(引用是从变量到对象的指针)。

举例,当我们定义如下函数时:>>> def hi(name = "Jason"):

return "Hi! " + name

>>> print hi()

Hi! Jason

我们可以将函数赋值给一个变量(我们这里不使用小括号,因为我们并不准备调用 hi 函数):>>> hello = hi

>>> hi()

'Hi! Jason'

>>> hello()

'Hi! Jason'

>>> hi

>>> type(hi)

>>> type(hello)

>>> id(hi)

44709744

>>> id(hello)

44709744

>>> #hi 和 hello 属于同一类型,指向了同一个对象

调用 hi 函数:>>> hello = hi()

>>> type(hello)

>>> id(hello)

44730208

>>> #hello 对象的类型和标识被更改

如果我们删掉 hi 函数:>>> hello

'Hi! Jason'

>>> hi()

'Hi! Jason'

>>> del hi

>>> hi

Traceback (most recent call last):

File "", line 1, in

hi

NameError: name 'hi' is not defined

>>> hello

'Hi! Jason'

>>>

hi 函数不再存在,hello 变量指向的对象不受影响。



本文参考 Python 3.5.5 documentation 的 Language Reference,链接地址为 docs.python.org/3.5/reference/

[return]

在某些情况下,在某些可控的条件下,是可以更改对象的类型的。但它一般不是好主意,因为如果它处理不正确,可能导致一些非常奇怪的行为。

[return]