Python对象问题

问题描述:

老师,python不是面向对象的吗,这个结果怎么为true?

同学的代码

a = {1,2,3}
b = {1,2,3,4,5} - {4,5}
print (a == b)
#True

问题解答:

首先这个问题跟Python是否是面对对象是没有关系的,面对对象编程是一种思想,Python是面对对象的编程语言,但跟这个问题无关。

Python的对象包含着3个要素:

  • id:用来唯一标识对象,就像身份证号码代表唯一的你。
  • type:标识对象的类型,比如,整数型int。
  • value:对象的值。

而对象的名字只是对象的引用,言外之意就是说同一个对象( object )可以有不同的名字( 引用 ),就比如你有身份证的名字,但也有小时候的乳名。

所以这位同学问题中a == b的值是True是没有问题的,但是a == b的意思是a的值(value)等于b,而不是说a对象就是b对象。在Python中,有一个is关键字来判断两个对象是否是同一个对象(也就是说id是否一样),或者用内置函数id()来输出对象的id值判断,如下:

>>> a = {1,2,3}
>>> b = {1,2,3,4,5} - {4,5}
>>> print (a == b)
True
>>> print (a is b)
False
>>> print (id(a),id(b))
4338869416 4338870760

可见,a与b的值相等,id不相等,问题也就弄清楚了。

问题延伸:

先看以下代码:

>>> a = 1
>>> b = 5 - 4
>>> a is b
True
>>> a == b
True
>>> id(a),id(b)
(4297537792, 4297537792)

为什么这种情况下,a与b的value和id都相等呢?

这就要回溯到Python源代码(C语言代码)本身了。Python中整数1,2,3等都是对象,而且会被引用得特别多,为了提高Python的运行效率,引入了整数对象池的机制。你不用理解什么是整数对象池机制,你只要记住,当整数对象数值相等,而且大小在[-5, 256)范围内,那就为这个整数值只开辟一个内存地址(id),超过这个范围,则重新开辟内存地址,如下(整数数值在[-5,256)之外):

>>> a = -6
>>> b = -6
>>> a is b
False
>>> a == b
True
>>> id(a),id(b)
(4338513008, 4338513040)

对于string对象,源码实现有一个操作叫intern,在新建string对象时会校验其内容,如果在intern池内有一样的就会把引用指过去,所以id也是一样的,如下:

>>> a = '1234567'
>>> b = '1234567'
>>> a is b
True
>>> a == b
True
>>> id(a),id(b)
(4338891608, 4338891608)

对float对象,由于float太多了,所以每一次创建对象都开辟新内存(id)。还有,对于dict,list和tuple对象都是如此,如下:

>>> a = 1.1
>>> b = 1.1
>>> a is b
False
>>> a = [1]
>>> b = [1]
>>> a is b
False
>>> a = (1,)
>>> b = (1,)
>>> a is b
False
>>> a = {}
>>> b = {}
>>> a is b
False

results matching ""

    No results matching ""