Python对象和引用

Python对象概述

计算机程序通常用于处理各种类型的数据(即对象),不同的数据属于不同的数据类型,支持不同的运算操作。在Python语言中,数据表示为对象。对象本质上是一个内存块,拥有特定的值,支持特定类型的运算操作。在Python3中,一切皆为对象。Python语言中的每个对象由标识(identity)、类型(type)和值(value)标识。

(1)标识用于唯一地标识一个对象,通常对应对象在计算机内存中的位置。使用内置函数id(obj1)可以返回对象obj1的标识。

(2)类型用于表示对象所属的数据类型(类),数据类型用于限定对象的取值范围以及允许执行的处理操作。使用内置函数type(obj1)可以返回对象obj1所属的数据类型。

(3)用于表示对象的数据类型的值。使用内置函数print(obj1)可以返回对象objl的值。

通过内置的type()函数可以判断一个对象的类型。通过内置的id()函数可以获取一个对象唯一的id标识(CPython的实现为内存存放位置)。

【实例】 使用内置函数type()、id()和print()查看对象。

123              #输出:123
id(123)          #输出:140706558370656
type(123)        #输出:<class'int'>
print(123)       #输出:123

字面量123创建一个实例对象,其id标识为140706558370656,类型为int类型,值为123。在Python 3中函数等也是对象,也具有相应的类型和id。

【实例】 查看Python的内置函数对象。

type(abs)         #输出:<class'builtin function or method'>
id(abs)           #输出:2529313427104
type(range)       #输出:<class'type'>
id(range)         #输出:140706557885440

使用字面量创建实例对象

对于内置对象, Python通常提供使用字面量直接创建实例对象的语法。

Python的数据类型定义了一个值的集合,在Python代码中使用字面量表示某个数据类型的值。例如,12、101等表示int数据类型的值;0.17、3.14等表示float数据类型的值;True和False表示bool数据类型的值;'Hello, World'、'张三'等表示str数据类型的值。字面量在Python语句中解释为表达式, Python基于字面量创建相应的数据类型的对象。

【实例】 使用字面量创建实例对象。

123      #输出:123
"abc"    #输出:'abc'

Python使用字面量123和“abc”分别创建一个int型对象和一个str型对象。

使用类对象创建实例对象

通过直接调用类对象可以创建实例对象,其语法格式如下。

类对象(参数)

【实例】使用类对象创建实例对象。

int(12)       #输出:12
complex(1,2)  #输出:(1+2j)

Python使用int(12)创建一个整数数据类型的实例对象;使用complex(1,2)创建一个复数类型的实例对象。另外,表达式的运算结果也可以创建新的对象;Python语句def会创建函数对象;class语句会创建类对象。

数据类型

在Python语言中,所有对象都有一个数据类型。Python数据类型的定义为一个值的集合以及在这个值集上的一组运算操作。

例如整数数据类型(int),其值的集合为所有的整数,支持的运算操作包括+(加法)、-(减法)、*(乘法)、//(整除)等,88、1024等都是整数类型数据。

每个对象存储一个值,例如, int类型的对象可以存储值1234、99或1333。不同的对象可以存储同一个值,例如,一个str类型的对象可以存储值'hello',另一个str类型的对象也可以存储值'hello'。在一个对象上可执行且只允许执行其对应数据类型定义的操作,例如,两个int对象可执行乘法运算,但两个str对象不允许执行乘法运算。

Python数据类型包括内置数据类型自定义数据类型。Python语言提供了丰富的内置数据类型,用于有效地处理各种类型的数据。

变量和对象的引用

Python对象是位于计算机内存中的一个内存数据块。为了引用对象,用户必须通过赋值语句把对象赋值给变量(也称之为把对象绑定到变量)。指向对象的引用即变量

【实例】 使用赋值语句把对象绑定到变量。

a=1     #字面量表达式1创建值为1的int型实例对象,并绑定到变量a
b=2     #字面量表达式2创建值为2的int型实例对象,并绑定到变量b
c=a+b   #表达式a+b创建值为3的int型实例对象,并绑定到变量c

Python使用字面量表达式1、2和表达式a+b创建3个整型对象,并使用赋值语句把3个对象分别绑定到变量a、b和c。字面量用于创建值为字面量的对象,即某个数据类型的实例对象;表达式使用运算符实现多个操作数(对象)的运算操作,并返回结果对象。用户可以把对象通过赋值语句赋值给一个变量,即把对象绑定到一个变量,注意变量名必须为有效的标识符

在Python 3中,作为对象的函数和类等也可以通过变量引用,但这样的引用一般意义不大,建议直接使用函数/类,以提高程序的可读性。例如:

x=abs
x(−123)                    #输出:123
y=str
id(y)                      #输出:140706557890640
y.format('{0:.2f}',123)    #输出:'123.00'

Python是动态类型语言

Python是动态类型语言,即变量不需要显式声明数据类型。根据变量的赋值, Python解释器自动确定其数据类型。事实上,变量仅用于指向某个类型对象,因此变量可以不限定类型,即可以指向任何类型的对象。通过标识符和赋值运算符(=)可以指定某个变量指向某个对象,即引用该对象。多个变量可以引用同一个对象,一个变量也可以改变指向其他的对象

【实例】变量的动态类型示例。

type(123)      #输出:<class'int'>
id(123)        #输出:140706558370656
a = 123
id(a)          #输出:140706558370656
b = 123
id(b)          #输出:140706558370656
c = a
id(c)          #输出:140706558370656
id('abc')      #输出:2529314137232
a = 'abc'
id(a)          #输出:2529314137232

123为类int的对象实例,其id为140706558370656;a=123,即变量a指向(引用)对象实例123,故其id也为140706558370656;b=123,即变量b也指向(引用)对象实例123,故其id也为140706558370656;c=a,变量c和变量a一样,指向(引用)对象实例123,其id同样为140706558370656。a='abc',变量a指向(引用)对象实例'abc',其id为2529314137232。

Python是强类型语言

Python是一种强类型语言,每个变量指向的对象均属于某个数据类型,即只支持该类型允许的运算操作。

【实例】变量的强数据类型示例。

a=1           #a指向值为1的int型实例对象
b= "11"       #b指向值为"11"的str型实例对象
a+b           #错误:int型和str型对象不能直接相加,即str型对象不能自动转换为int型对象

对象内存示意图

Python程序运行时会在内存中创建各种对象(位于堆内存中),通过赋值语句可以将对象绑定到变量(位于栈内存中),从而通过变量引用对象进行各种操作。多个变量可以引用同一个对象如果一个对象不再被任何有效作用域中的变量引用,则会通过自动垃圾回收机制回收该对象占用的内存

【实例】变量增量运算示例以及相应的对象内存示意图。

i=100
i=i+1

第1条语句,创建一个值为100的int对象,并绑定到变量i;第2条语句,先计算表达式i+1的值,然后创建一个值为101的int对象,并绑定到变量i。注意:在执行完第2条语句后,内存中存在3个int对象,即100、1和101,变量i引用对象101,其他两个对象没有被任何变量引用,将被自动垃圾回收器回收。

【实例】交换两个变量的示例。

a=123   #a指向值为123的int型实例对象
b=456   #b指向值为456的int型实例对象
t=a     #变量t和a一样,指向(引用)对象实例123
a=b     #变量a和b一样,指向(引用)对象实例456
b=t     #变量b和t一样,指向(引用)对象实例123

对象的值比较和引用判别

通过==运算符可以判断两个变量指向的对象的值是否相同;通过is运算符可以判断两个变量是否指向同一个对象。

【实例】 对象的值比较(==)和引用判别(is)示例。

x = 'abc'      #x指向值为"abc"的str型实例对象
y = x          #变量y和x一样,指向(引用)对象实例"abc"
z = 'abcd'     #z指向值为"abcd"的str型实例对象
x == y         #输出:True
x is y         #输出:True
x == z         #输出:False
x is z         #输出:False

不可变对象和可变对象

Python 3对象可以分为不可变对象(immutable)和可变对象(mutable)。

不可变对象一旦创建,其值就不能被修改;可变对象的值可以被修改。Python对象的可变性取决于其数据类型的设计,即是否允许改变其值。

Python中的大部分对象都是不可变对象,例如bool、int、float、str、complex、tuple等。变量是指向某个对象的引用,多个变量可以指向同一个对象。给变量重新赋值,并不改变原始对象的值,只是创建一个新对象,并指向该变量。

【实例】 不可变对象示例。

a = 18         #变量a指向int对象18
id(a)          #输出:140706365363776.表示a指向的int对象18的id
a = 25         #变量a指向int对象25
id(a)          #输出:140706365364000.表示a指向的int对象25的id
b = 25         #变量b指向int对象25
id(b)          #输出:140706365364000.表示b指向的int对象25的id
id(25)         #输出:140706365364000.表示int对象25的id

对象本身的值可以改变的对象称为可变对象(例如set、list、dict等)。

【实例2.13】可变对象示例。

x = y = [1,2,3]    #变量x和y指向list对象[1,2,3]
id(x)              #输出:1656936944328.表示变量x指向的list对象[1,2,3]的id
id(y)              #输出:1656936944328.表示变量y指向的list对象[1,2,3]的id
x.append(4)        #变量x指向的list对象[1,2,3]附加一个元素4
x                  #输出:[1,2,3,4].表示变量x指向的list对象[1,2,3,4]
id(x)              #输出:1656936944328.变量x指向的list对象[1,2,3,4]的id未改变
x is y             #输出:True.表示变量x和y指向同一个list对象[1,2,3,4]
x == y             #输出:True.表示变量x和y指向的list对象值相等
z = [1,2,3,4]      #变量z指向的list对象[1,2,3,4]
id(z)              #输出:1656965757064.表示变量z指向的list对象[1,2,3,4]的id
x is z             #输出:False.表示变量x和z指向不同的list对象[1,2,3,4]
x == z             #输出:True.表示变量x和z指向的list对象值相等