【Python】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

回答

根据 python 官方文档, id() 函数解释如下

In [1]: id?

Signature: id(obj, /)

Docstring:

Return the identity of an object.

This is guaranteed to be unique among simultaneously existing objects.

(CPython uses the object's memory address.)

Type: builtin_function_or_method

input() 函数返回的是动态创建的字符串,它的内存地址不是预知的。
tt2 = 'TT'; tt3 = 'TT'; 这种, python 解释器只会保存第一个 ‘TT’ 字符串,第二个 ‘TT’ 被引向前面那个。因此它们的 id() 结果相同。改变 tt2tt3 将导致新的字符串产生,而不会改变 ‘TT’ 内容。

这个问题看似简单,但是却触及到了计算机的底层!!!

根据《深入理解计算机系统》这本书的第一章节所提:信息 就是位 + 上下文。

【Python】python input 获取到的字符串不能使用is 判断

那么,我们看看 Python 是 如何对 id() 函数定义的:

>>>help(id)

Help on built-in function id in module builtins:

id(obj, /)

Return the identity of an object.

This is guaranteed to be unique among simultaneously existing objects.

(CPython uses the object's memory address.)

(END)

显而易见,id(object) 函数是返回对象 object 位于内存中的地址。
但是,根据《深入理解计算机系统》对 信息 的定义, 你会认识到 python 文档一贯轻佻的调性,这里没有提 上下文, 没有提对象的生命周期,这是不严谨的。因为没有提到重要的上下文关系。

为了更好的理解,特别是 生命周期,也就是上下文关系,

我做了两个脚本:

test1.py 内容如下:

print(__name__)

test1 = input('ttt>>>').strip()

print(test1)

print(id(test1))

test2 = 'TT'

print(id(test2))

test2.py 内容如下:

test3 = 'TT'

print(__name__)

print(id(test3))

运行第一个脚本,显示主程是 __main__,结果,你会发现和题主的脚本是一样的,两个 id 是不一样的。
运行第二个脚本,显示主程是 __main__,结果,你会发现这里的 id 和第一也是不一样的。

也就是说,对象的对应的 内存地址 是不一样的,因为,上下文 ,或者说程序的生命周期不一样。

更直观点,你运行第一个脚本很多遍,每次 id 显示的内容几乎都是不一样的。
运行第二个脚本也是如此。
至于为什么我用 几乎这个词,还是留给你们自行查资料把。

>>> test = input('TT>>')

TT>>'TT'

>>> test2 = 'TT'

>>> id(test)

4401760416

>>> id(test2)

4401760416

以上是在Python2环境下的执行结果。二者id是相同的。
所以,题主真正需要了解的应该是python2和python3环境下,input的区别。

==和is如何选择?

==运算符比较两个对象的值,可以使用__eq__魔术方法重载实现自定义比较。
is比较两个对象的id标识,不能重载,通常用于变量和单例值直接的比较,比如is None。

为什么有时id相同?

首先id并不会因为是不可变类型就相同。
Cpython有一种叫驻留(interning)的细节优化手段,会为字符串还有小的整数做出优化,共享同一个引用。
但是注意这种优化既不适用不可变类型,也不适用所有的字符串和整数,具体情况参考源码实现。

以上是 【Python】python input 获取到的字符串不能使用is 判断 的全部内容, 来源链接: utcz.com/a/79482.html

回到顶部