关于不可变字符串的更改id

关于不可变字符串的更改id

关于id类型对象str(在python 2.7中)令我困惑。这个str类型是不可变的,所以我希望一旦它被创建,它将始终具有相同的类型。id..我相信我不是很好的表达自己,所以我会张贴一个输入和输出序列的例子。

>>> id('so')140614155123888>>> id('so')140614155123848>>> id('so')140614155123808

所以在这段时间里,它一直在变化。但是,在变量指向该字符串后,情况会发生变化:

>>> so = 'so'>>> id('so')140614155123728>>> so = 'so'>>> id(so)140614155123728>>> not_so = 'so'>>> id(not_so)140614155123728

因此,一旦变量持有该值,它就会冻结id。实际上,之后del sodel not_so的输出id('so')再换一次。

这是与(小)整数相同的行为。

我知道不变性和拥有同样的东西之间没有真正的联系。id尽管如此,我仍在努力找出这种行为的根源。我相信熟悉蟒蛇内部结构的人会比我更不惊讶,所以我试图达到同样的程度.

更新

用不同的字符串做同样的尝试会产生不同的结果.

>>> id('hello')139978087896384>>> id('hello')139978087896384>>> id('hello')139978087896384

现在它平等.。


犯罪嫌疑人X
浏览 500回答 3
3回答

四季花海

此行为特定于Python交互式shell。如果我将以下内容放入.py文件中:print id('so')print id('so')print id('so')并执行它,我将收到以下输出:2888960 2888960 2888960在CPython中,字符串文本被视为常量,我们可以在上面片段的字节码中看到:  2           0 LOAD_GLOBAL              0 (id)               3 LOAD_CONST               1 ('so')               6 CALL_FUNCTION            1               9 PRINT_ITEM                        10 PRINT_NEWLINE          3          11 LOAD_GLOBAL              0 (id)              14 LOAD_CONST               1 ('so')              17 CALL_FUNCTION            1              20 PRINT_ITEM                        21 PRINT_NEWLINE          4          22 LOAD_GLOBAL              0 (id)              25 LOAD_CONST               1 ('so')              28 CALL_FUNCTION            1              31 PRINT_ITEM                        32 PRINT_NEWLINE                     33 LOAD_CONST               0 (None)              36 RETURN_VALUE这个同常量(即相同的字符串对象)被加载3次,因此ID是相同的。

蝴蝶刀刀

因此,虽然Python不能保证对字符串进行实习,但它将经常重用相同的字符串,并且is可能会误导。重要的是要知道你不应该检查id或is为了相等的字符串。为了演示这一点,我发现了一种至少在Python2.6中强制使用新字符串的方法:>>> so = 'so'>>> new_so = '{0}'.format(so)>>> so is new_so  False下面是Python的一些探索:>>> id(so)102596064>>> id(new_so)259679968>>> so == new_soTrue
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python