python中的对象身份比较操作符的是_Python 对象

2ff34e647e2e3cdfd8dca593e17d9b0a.png

Python 对象

Python 使用对象模型来存储数据。构造任何类型的值都是一个对象。

所有的 Python 对像都拥有三个特性:身份,类型和值。身份

每一个对象都有一个唯一的身份标识自己,任何对象的身份可以使用内建函数id()来得到。这个值可以被认为是该对象的内存地址。

类型

对象的类型决定了该对象可以保存什么类型的值,可以进行什么样的操作,以及遵循什么样的规则。您可以用内建函数 type()查看 Python 对象的类型。因为在 Python 中类型也是对象,所以type()返回的是对象而不是简单的 字符串。

对象表示的数据项

上面三个特性在对象创建的时候就被赋值,除了值之外,其它两个特性都是只读的。对于 新风格的类型和类, 对象的类型也是可以改变的。

类型对象和type类型对象

虽然看上去把类型本身也当成对象有点特别,我们 还是要在这里提一提。你一定还记得,对象的一系列固有行为和特性(比如支持哪些运算,具 有哪些方法)必须事先定义好。从这个角度看,类型正是保存这些信息的最佳位置。描述一种 类型所需要的信息不可能用一个字符串来搞定,所以类型不能是一个简单的字符串,这些信息 不能也不应该和数据保存在一起, 所以我们将类型定义成对象。

下面我们来正式介绍内建函数type()。通过调用 type()函数你能够得到特定对象的类型 信息:1

2>>> type(42)

您看到的实际上是一个类型对象,碰巧它输出了一个字符串来告诉你 它是个int 型对象。

那么类型对象的类型是什么?1

2>>> type(type(42))

没错,所有类型对象的类型都是 type,它也是所有 Python 类型的根和所有 Python 标准类 的默认元类(metaclass)。

None,Python 的 Null 对象

Python有一个特殊的类型,被称作 Null 对象或者 NoneType,它只有一个值,那就是 None。 它不支持任何运算也没有任何内建方法。如果非常熟悉 C 语言,和 None 类型最接近的 C 类型就 是 void,None 类型的值和 C 的 NULL 值非常相似(其他类似的对象和值包括 Perl 的 undef 和 Java 的 void 类型与 null 值)。

None 没有什么有用的属性,它的布尔值总是 False。

对象的布尔值

所有标准对象均可用于布尔测试,同类型的对象之间可以比较大小。

每个对象天生具有布 尔 True 或False 值。空对象、值为零的任何数字或者 Null 对象 None 的布尔值都是 False。

下列对象的布尔值是 False。None

False (布尔类型)

所有的值为零的数

0 (整型)

0.0 (浮点型)

0L (长整型)

0.0+0.0j (复数)

"" (空字符串)

[] (空列表)

() (空元组)

{} (空字典)

set()(空集合)

值不是上面列出来的任何值的对象的布尔值都是 True,例如 non-empty、non-zero 等等。

用户创建的类实例如果定义了 nonzero(__nonzero__())或length(__len__())且值为 0,那 么它们的布尔值就是False。

标准类型运算符

对象值的比较

比较运算符用来判断同类型对象是否相等,所有的内建类型均支持比较运算,比较运算返 回布尔值 True 或 False。1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

162 == 2

True

2.46 <= 8.33

True

5+4j >= 2-3j

True

'abc' == 'xyz'

False

'abc' > 'xyz'

False

>>>'abc' < 'xyz'

True

>>>[3, 'abc'] == ['abc', 3]

False

>>>[3, 'abc'] == [3, 'abc']

True

不同于很多其它语言,多个比较操作可以在同一行上进行,求值顺序为从左到右。1

2

3

4

5

6>>>3 < 4 < 7

True

>>>4 > 3 == 3 #sameas(4>3)and(3==3)

True

>>>4 < 3 < 5 != 2 < 7

False

其实这个表达式本质上是由 多个隐式的 and 连接起来的多个表达式。1

2>>>3 < 4 < 7 #sameas"( 3 < 4 ) and ( 4 < 7 )"

True

我们会注意到比较操作是针对对象的值进行的,也就是说比较的是对象的数值而不是对象 本身。

对象身份比较

作为对值比较的补充,Python 也支持对象本身的比较。对象可以被赋值到另一个变量(通 过引用)。因为每个变量都指向同一个(共享的)数据对象,只要任何一个引用发生改变,该对 象的其它引用也会随之改变。

为了方便大家理解,最好先别考虑变量的值,而是将变量名看作对象的一个链接。

Python 提供了is 和 is not 运算符来测试两个变量是否指向同一个对象。象下面这样执行一个测试1a is b

这个表达式等价于下面的表达式1id(a) == id(b)

标准类型对象身份比较运算符:运算符功能obj1 is obj2obj1 和 obj2 是同一个对象

obj1 is not obj2obj1 和 obj2 不是同一个对象

整型和字符串缓存

在上面的例子中,您会注意到我们使用的是浮点数而不是整数。为什么这样?

整数对象和 字符串对象是不可变对象,所以Python会很高效的缓存它们。这会造成我们认为Python应该

创建新对象时,它却没有创建新对象的假象。看下面的例子:1

2

3

4

5

6

7

8

9

10

11

12

13

14>>>a = 1

>>>id(a)

8402824

>>>b = 1

>>>id(b)

8402824

>>>

>>>c = 1.0

>>>id(c)

8651220

>>>d = 1.0

>>>id(d)

8651204

在上面的例子中,a 和 b 指向了相同的整数对象,但是 c 和 d 并没有指向相同的浮点数 对象。

如果我们是纯粹主义者,我们会希望 a 与 b 能和 c 与 d 一样,因为我们本意就是为 了创建两个整数对象,而不是像 b = a 这样的结果。

Python 仅缓存简单整数,因为它认为在 Python 应用程序中这些小整数会经常被用到。

Python 缓存的整数范围是(-1, 100),不过这个范围是会改变的,所 以请不要在你的应用程序使用这个特性。Python 2.3 中决定,在预定义缓存字符串表之外的字符串,如果不再有任何引用指向它, 那这个字符串将不会被缓存。也就是说, 被缓存的字符串将不会象以前那样永生不灭,对象回 收器一样可以回收不再被使用的字符串。

标准类型内建函数

Python 提供了一些内建函数用于这些基本对象类型:cmp(), repr(), str(), type(), 和等同于 repr()函数的单反引号 (``)运算符。

标准类型内建函数:cmp(obj1, obj2):比较 obj1 和 obj2, 根据比较结果返回整数 i:1

2

3i < 0 if obj1 < obj2

i > 0 if obj1 > obj2

i == 0 if obj1 == obj2

repr(obj) 或 `obj`:返回一个对象的字符串表示

str(obj):返回对象适合可读性好的字符串表示

type(obj):到一个对象的类型,并返回相应的 type 对象

type()

在 Python2.2 以前,type() 是内建函数。不过从那时起, 它变成了一个“工厂函数”。后面部分我们会讨论工厂函数, 现在你仍然可以将type()仅仅当成一个内建函数来看。 type() 的用法如下:type(object)

type() 接受一个对象做为参数,并返回它的类型。它的返回值是一个type类型对象。1

2

3

4

5

6

7

8>>>type(4) # int type

>>>

>>>type('Hello World!') # string type

>>>

>>>type(type(4)) # type type

在上面的例子里, 我们通过内建函数 type() 得到了一个整数和一个字符串的类型;为了 确认一下类型本身也是类型, 我们对 type()的返回值再次调用 type()。

注意type()有趣的 输出, 它看上去不象一个典型的 Python 数据类型, 比如一个整数或一个字符串,一些东西被 一个大于号和一个小号包裹着。这种语法是为了告诉你它是一个对象。每个对象都可以实现一 个可打印的字符串表示。不过并不总是这样, 对那些不容易显示的对象来说, Python 会以一 个相对标准的格式表示这个对象,格式通常是这种形式:,以 这种形式显示的对象通常会提供对象类别,对象 id 或位置, 或者其它合适的信息。

cmp()

内建函数 cmp()用于比较两个对象 obj1 和 obj2,

如果 obj1 小于 obj2,则返回一个负整 数,

如果 obj1 大于 obj2 则返回一个正整数,

如果 obj1 等于 obj2, 则返回 0。

它的行为非常 类似于 C 语言的 strcmp()函数。比较是在对象之间进行的,不管是标准类型对象还是用户自定 义对象。如果是用户自定义对象,cmp()会调用该类的特殊方法__cmp__()。

下面是几个使用 cmp()内建函数的对数值和字符串对象进行比较的例子。1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17>>>a, b = -4, 12

>>>cmp(a,b)

-1

>>>cmp(b,a)

1

>>>b = -4

>>>cmp(a,b)

0

>>>

>>>a, b = 'abc', 'xyz'

>>>cmp(a,b)

-23

>>>cmp(b,a)

23

>>>b = 'abc'

>>>cmp(a,b)

0

str()和repr() (及 `` 运算符)

内建函数str() 和repr() 或反引号运算符(``) 可以方便的以字符串的方式获取对象的 内容、类型、数值属性等信息。

str()函数得到的字符串可读性好, 而 repr()函数得到的字符串通常可以用来重新获得该对象,通常情况下 obj == eval(repr(obj))这个等式是成立的。

这两个函数接受一个对象做为其参数, 返回适当的字符串。1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17>>>str(4.53-2j)

'(4.53-2j)'

>>>

>>>str(1)

'1'

>>>

>>>str(2e10)

'20000000000.0'

>>>

>>>str([0, 5, 9, 9])

'[0, 5, 9, 9]'

>>>

>>>repr([0, 5, 9, 9])

'[0, 5, 9, 9]'

>>>

>>>`[0, 5, 9, 9]`

'[0, 5, 9, 9]'

尽管 str(),repr()和``运算在特性和功能方面都非常相似, 事实上repr() 和 `` 做的 是完全一样的事情,它们返回的是一个对象的“官方”字符串表示, 也就是说绝大多数情况下 可以通过求值运算(使用 eval()内建函数)重新得到该对象,但 str()则有所不同。str() 致力 于生成一个对象的可读性好的字符串表示,它的返回结果通常无法用于eval()求值, 但很适 合用于 print 语句输出。需要再次提醒一下的是, 并不是所有repr()返回的字符串都能够用eval()内建函数得到原来的对象:1

2

3

4>>>eval(`type(type))`)

File "", line 1 eval(`type(type))`)

^

SyntaxError: invalid syntax

也就是说 repr()输出对 Python 比较友好, 而 str()的输出对人比较友好。事实上 Python 社区目前已经不鼓励继续使用``运算符。

type() 和isinstance()

未完,待续…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值