Python防止掉坑之 is 函数

来源:互联网 发布:打印设置软件 编辑:程序博客网 时间:2024/06/16 07:24

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

# 第一组>>> a = 256>>> b = 256>>> a is bTrue# 第二组>>> a = 257>>> b = 257>>> a is bFalse# 第三组>>> a = 257; b = 257>>> a is bTrue

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

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


科普知识

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

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


拓展案例

# test.py# -*- coding: utf-8 -*-a = 257b = 257def func():    c = 257    print(a is c)  # Falseprint(a is b)  # Truefunc()

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

原创粉丝点击