Python防止掉坑之 is 函数

每种编程语言都有一些不为人知的陷阱,有些实际工作中会踩到,有些可能根本排不上用场,但弄明白这些陷阱有利于我们更好的去了解这门语言的实现机制。
下面这道题,你是否能一眼看出问题的本质。

# 第一组
>>> a = 256
>>> b = 256
>>> a is b
True
# 第二组
>>> a = 257
>>> b = 257
>>> a is b
False
# 第三组
>>> a = 257; b = 257
>>> a is b
True

我们知道 is 函数比较的是两个对象的内存地址是否一样吗,id 函数返回一个和对象的内存地址相关的值)。言外之意,就是可以通过查看每个变量的 id 值来判断两个变量知否指向同一个对象。

PS:在 Python 的交互式命令行 REPL 中,每单独一行都视为一个代码块,同一行中的代码属于同一个代码块。因此不难理解,第三组中的a和b处在同一个代码块中,所以后者重用了前者,因此,两个变量的id是相同的。


科普知识

同样的,为了提高性能,Python 就把一些常用的整数专门缓存起来,就像屋子里面有些东西总是每天都要频繁使用,比如床,不能睡完之后就把床搬出去,要用了再搬回来,这样的效率太低了,因为整个搬运过程很耗时间的。于是,我们可以专门拿一块空间用来放置这个床。

Python 中也是同样的道理,因为整数是我们经常使用的对象,为了避免重复的创建、回收,干脆就把那些常用的整数缓存起来,每次需要使用时直接从缓存中拿,而不是重新创建(重新创建的话,肯定是一个全新的对象)。这些整数的范围是[-5, 256],当然这个数字范围是Python之父决定的,你要改,必须重新编译Python环境。


拓展案例

# test.py
# -*- coding: utf-8 -*-
a = 257
b = 257

def func():
    c = 257
    print(a is c)  # False

print(a is b)  # True

func()

上面代码是在一个 test.py 文件中,运行时,a和b的id值相同,而c的id值与a不一样,因为a、b 在同一个代码块,属于模块级别,而 c 是在函数里面,属于局部变量,他们不属于同一代码块中,因此函数里面的 257 这个对象时会重新创建,而创建 b 的时候,发现同级代码块中有个257的值了,就重用了这个对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值