Python对象(下)

前面一篇文章介绍了一些Python对象的基本概念,这篇接着来看看Python对象相关的一些内容。

Python对象的比较

Python对象有三个要素:身份,类型和值,所以我们就分别从这三个角度出发看看对象之间的比较。

对象身份比较

对象身份的比较,其实就是比较对象的内存地址,即内建函数id()的结果比较。可以用来判断不同的变量是否指向了同一个地址。

直接看例子:

通过例子的输出可以得到,f1和f2指向了不同的对象(地址);但是,i1和i2却指向了相同的对象(地址)。

之所以产生这种差异,是因为Python对整数对象和字符串对象会进行缓存,所以没有产生新的对象,而是指向了缓存的对象。不同版本的Python处理缓存是不一样的,所以同样的例子可能产生不同的结果。

对于对象身份比较,还可以使用Python中的"is"关键字:

obj1 is obj2
# 等价
id(obj1) == id(obj2)

obj1 is not obj2
# 等价
id(obj1) != id(obj2)

对象类型比较

通过type()内建函数,可以得到一个对象的类型,然后就可以进行类型比较了。

看一段代码:

例子中使用了三种方式进行对象类型的比较:

  • 直接将type(obj)与类型进行比较
  • 将type(obj)的身份跟类型的身份进行比较
  • 通过内建的isinstance()函数,判断一个对象是不是有特定类型实例化得到的
    • 其第一个参数为对象,第二个为类型名或类型名的一个列表
    • 其返回值为布尔型

简单看看前两种方式的区别,第一种方式是直接将两个类型对象的值进行比较;而第二种方式比较的是两个类型对象的身份,这种方式的原理是,如果两个类型对象的身份不同,那么两个类型对象的值肯定不同。

对象值比较

对于Python对象,可以直接使用比较操作符(>,<,==等)进行对象值的比较。关于Python的内建对象,有一套比较规则,比如两个list对象的比较就是按照list比较规则进行的。

这里我们就主要看看自定义类型的对象之间的比较。

自定义类型的对象值比较

在Python中,所有的类型都有一套用于比较的"魔术方法" ,对于自定义的类型,我们就可以通过实现这些方法来定义自定义类型的对象的比较行为:

  • __cmp__(self, other) : __cmp__ is the most basic of the comparison magic methods. __cmp__ should return a negative integer if self < other, zero if self == other, and positive if self > other.
  • __eq__(self, other) Defines behavior for the equality operator, ==.
  • __ne__(self, other) Defines behavior for the inequality operator, !=.
  • __lt__(self, other) Defines behavior for the less-than operator, <.
  • __gt__(self, other) Defines behavior for the greater-than operator, >.
  • __le__(self, other) Defines behavior for the less-than-or-equal-to operator, <=.
  • __ge__(self, other) Defines behavior for the greater-than-or-equal-to operator, >=.

看一个例子,我们定义了一个"语句"类型,并实现了一些比较方法,这样对于改类型的对象,我们就可以直接通过比较操作符进行对象值比较了。

有一点需要注意的是,关于自定义类型的对象,如果没有实现比较操作符对应的"魔术方法",那么将默认使用对象身份(id())进行比较。

"is"和"=="的差别

这里需要注意一下"is"和"=="之间的差别:

  • "is"用来比较对象的身份是否相等,也就是说,比较对象的内存地址是否相同(变量是否指向同一个对象)
  • "=="用来比较对象的内容(值)是否相等

看下面的代码:

对于变量c和d,由于数值超过了Python对整型数的缓存范围,所有d就会是Python生成的一个新的对象。因此,c和d的值是相同的,但是身份却是不同的。

可变对象和不可变对象

在Python中,一切都是对象,Python中不存在所谓的传值,一切传递的都是对象的引用(也可以认为是传址)。

上一篇文章中了解到,根据Python对象的类型,可以将Python对象分为:Type Object(类型对象)和Non-type Object(非类型对象)。

同样,根据对象的可变性,也可以将Python对象分为两类:可变(mutable)对象和不可变(immutable)对象。

  • 不可变(immutable)对象:对象的内容不可变,当尝试改变对象内容的时候,会创建一个新的对象;也就是说对象的身份(id())会发生变化

    • 例如:number、string,tuple
  • 可变(mutable)对象:对象的内容可变,当改变对象内容的时候,对象的身份(id())不会变化
    • 例如:list、dict、set

看一段简单的代码:

tuple是"可变的"

虽然元组对象本身是不可变的,但这并不意味着元组包含的可变对象也不可变。

看下面的例子:

现在我们根据下图分析这段代码,tpl这个元组的第四个元素比较特殊,是一个list;所以,在tpl中第四个元素存放的是这个list的地址(身份id(),引用)。

元组的不可变性就决定了tpl第四个元素对应的内容,即list的地址不能改变了,但是,这个地址37865712指向的内容是可以被改变的。

总结

本篇介绍了Python对象的比较,包括对象的身份,类型以及值的比较。对于自定义类型的对象,如果需要进行比较操作,可以通过自定义比较操作相关的"魔术方法"。

另外,文中简单介绍了Python对象的可变性,对比了可变(mutable)对象和不可变(immutable)对象之间的不同。

时间: 2024-12-20 06:58:16

Python对象(下)的相关文章

python对象序列化或持久化的方法

http://blog.csdn.net/chen_lovelotus/article/details/7233293 一.Python对象持久化方法 目前为止,据我所知,在python中对象持久化有以下几种方法: 1. 使用(dbhash/bsddb, dbm, gdbm, dumbdbm 等)以及它们的"管理器"( anydbm ).只提供了 Python 字 符串的永久性储存. 提供一个类似字典和文件的对象,可以完成字符串的永久性存储. 2. 使用marshal和pickle来序

python源码剖析笔记1——Python对象初见

python源码剖析笔记1--Python对象初见 工作整两年了,用python最多,然而对于python内部机制不一定都清楚,每天沉醉于增删改查的简单逻辑编写,实在耗神.很多东西不用就忘记了,比如C语言,正好,python源码用C写的,分析python源码的同时又能温故C语言基础,实在是件很好的事情.另外,还有陈儒大神的<python源码剖析>做指引,分析也不至于没头没脑.期望在一个月的业余时间,能有所小成,以此为记. 1 python中的对象 python中,一切东西都是对象,在c语言实现

python 单下划线/双下划线使用总结(转载)

python 单下划线/双下划线使用总结 时间:2013-10-08 10:56来源:www.chengxuyuans.com Python 用下划线作为变量前缀和后缀指定特殊变量/方法. 主要存在四种情形1.    1. object # public    2. __object__ # special, python system use, user should not define like it    3. __object # private (name mangling duri

python 学习笔记day03-python基础、python对象、数字、函数

python基础 语句和语法 注释及续行 首要说明的是:尽管python可读性最好的语言之一,这并不意味者程序员在代码中就可以不写注释 和很多UNIX脚本类似,python注释语句从#字符开始 注释可以在一行的任何地方开始,解释器会忽略掉该行#之后的所有内容 一行过长的语句可以使用反斜杠\分解成几行 缩进及代码组 缩进相同的一组语句构成一个代码块,称之为代码组 首行以关键字开始,以冒号:结束,该行之后的一行或多行代码构成代码组 如果代码组只有一行,可以将其直接写在冒号后面,但是这样的写法可读性差

Python对象体系揭秘

Guido用C语言创造了Python,在Python的世界中一切皆为对象. 一.C视角中的Python对象 让我们一起追溯到源头,Python由C语言实现,且向外提供了C的API http://docs.python.org/c-api/index.html . 我们思考问题的时候,可能对于对象这种东西很容易理解,而计算机能理解的只有0,1序列这样的字节序列,从根本上讲,我们所说的计算机语言中的对象只是在内存中的一块内存空间里的0,1序列而已,这些连续或者非连续的内存空间在更高层次上可以看作是一

《python源码剖析》笔记 python对象初探

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.      在python中,对象就是为C中的结构体在堆上申请的一块内存.对象不能被静态初始化,也不能在栈空间生存.但内建的类型对象都是被静态初始化的. 2.      对象创建后大小不变.可变对象有一指针指向可变大小的内存区域. 3.      对象机制的基石:PyObject 定长对象: typedef struct _object{ PyObject_HEAD }PyObject

python学习手册——1介绍python对象类型

在python ,数据以对象的形式出现--无论是python提供的内置对象,还是使用python或是像C扩展库这样的扩展语言工具创建的对象.尽管在以后才能确定这一概念,但对象无非是内在中的一部分,包含数值和相关操作的集合. 由于对象是python 最基本的概念,从这一章开始我们将会全面地体验python的内置对象类型. python程序可以分解成模块,语句,表达式以及对象,如下所示: 1.程序由模块构成 2.模块包含语句 3.语句包含表达式 4.表达式建立并处理对象 为什么使用内置类型 1.内置

python核心编程第四章 python对象

4–1. Python 对象.与所有 Python 对象有关的三个属性是什么?请简单的描述一下.  身份,类型和值. 4–2. 类型.不可更改(immutable)指的是什么?Python 的哪些类型是可更改的 (mutable),哪些不是? 如果对象支持更新操作,那么它的值就可以改变,否则它的值也是只读的.对象的值是否 可以更改被称为对象的可改变性(mutability) 数字 Scalar 不可更改 直接访问 字符串 Scalar 不可更改 顺序访问 列表 Container 可更改 顺序访

04 Python 对象 - 《Python 核心编程》

?? Python 对象 ?? 内建类型 ?? 标准类型运算符 ?? 值的比较 ?? 对象身份比较 ?? 布尔类型 ?? 标准类型内建函数 ?? 标准类型总览 ?? 各种类型 ?? 不支持的类型 4.1 Python 对象 Python 使用对象模型来存储数据. 构造任何类型的值都是一个对象. 尽管Python 通常当成一种“面向对象的编程语言”,但你完全能够写出不使用任何类和实例的实用脚本. 不过Python 的对象语法和架构鼓励我们使用这些特性,下面让我们仔细研究一下Python 对象. 所