python input 获取到的字符串不能使用is 判断
test = input('TT >>').strip()
print(type(test))
print(type('TT'))
print(id(test))
print(id('TT'))
if test is "TT":
print('Yes')
上面的代码运行后,结果为
TT >>TT
<class 'str'>
<class 'str'>
4364442848
4364036392
我在输入那里写了字符串'TT',按道理变量这里获取到的就是字符串'TT',python的字符串类型是不可变,为什么我这里得到的 id 却不相同?
另一端测试代码
tt2 = 'TT'
tt3 = 'TT'
print(id(tt2))
print(id(tt3))
得到结果:
4314464360
4314464360
这里的id 就相同,难道input函数得到的返回值和这样直接赋值字符串有所不同吗?
环境是MAC下运行python3
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
根据 python 官方文档, id() 函数解释如下
用 input() 函数返回的是动态创建的字符串,它的内存地址不是预知的。
而 tt2 = 'TT'; tt3 = 'TT'; 这种, python 解释器只会保存第一个 ‘TT’ 字符串,第二个 ‘TT’ 被引向前面那个。因此它们的 id() 结果相同。改变 tt2 或 tt3 将导致新的字符串产生,而不会改变 ‘TT’ 内容。
这个问题看似简单,但是却触及到了计算机的底层!!!
根据《深入理解计算机系统》这本书的第一章节所提:信息 就是位 + 上下文。
那么,我们看看 Python 是 如何对 id() 函数定义的:
显而易见,id(object) 函数是返回对象 object 位于内存中的地址。
但是,根据《深入理解计算机系统》对 信息 的定义, 你会认识到 python 文档一贯轻佻的调性,这里没有提 上下文, 没有提对象的生命周期,这是不严谨的。因为没有提到重要的上下文关系。
为了更好的理解,特别是 生命周期,也就是上下文关系,
我做了两个脚本:
test1.py
内容如下:test2.py
内容如下:运行第一个脚本,显示主程是
__main__
,结果,你会发现和题主的脚本是一样的,两个 id 是不一样的。运行第二个脚本,显示主程是
__main__
,结果,你会发现这里的 id 和第一也是不一样的。也就是说,对象的对应的 内存地址 是不一样的,因为,上下文 ,或者说程序的生命周期不一样。
更直观点,你运行第一个脚本很多遍,每次 id 显示的内容几乎都是不一样的。
运行第二个脚本也是如此。
至于为什么我用 几乎这个词,还是留给你们自行查资料把。
以上是在Python2环境下的执行结果。二者id是相同的。
所以,题主真正需要了解的应该是python2和python3环境下,input的区别。
==和is如何选择?
==运算符比较两个对象的值,可以使用__eq__魔术方法重载实现自定义比较。
is比较两个对象的id标识,不能重载,通常用于变量和单例值直接的比较,比如is None。
为什么有时id相同?
首先id并不会因为是不可变类型就相同。
Cpython有一种叫驻留(interning)的细节优化手段,会为字符串还有小的整数做出优化,共享同一个引用。
但是注意这种优化既不适用不可变类型,也不适用所有的字符串和整数,具体情况参考源码实现。