test = input('TT >>').strip()
print(type(test))
print(type('TT'))
print(id(test))
print(id('TT'))
if test is "TT":
print('Yes')
上面的代碼運(yùn)行后,結(jié)果為
TT >>TT
<class 'str'>
<class 'str'>
4364442848
4364036392
我在輸入那里寫了字符串'TT',按道理變量這里獲取到的就是字符串'TT',python的字符串類型是不可變,為什么我這里得到的 id 卻不相同?
另一端測(cè)試代碼
tt2 = 'TT'
tt3 = 'TT'
print(id(tt2))
print(id(tt3))
得到結(jié)果:
4314464360
4314464360
這里的id 就相同,難道input函數(shù)得到的返回值和這樣直接賦值字符串有所不同嗎?
環(huán)境是MAC下運(yùn)行python3
==運(yùn)算符比較兩個(gè)對(duì)象的值,可以使用__eq__魔術(shù)方法重載實(shí)現(xiàn)自定義比較。
is比較兩個(gè)對(duì)象的id標(biāo)識(shí),不能重載,通常用于變量和單例值直接的比較,比如is None。
首先id并不會(huì)因?yàn)槭遣豢勺冾愋途拖嗤?br>Cpython有一種叫駐留(interning)的細(xì)節(jié)優(yōu)化手段,會(huì)為字符串還有小的整數(shù)做出優(yōu)化,共享同一個(gè)引用。
但是注意這種優(yōu)化既不適用不可變類型,也不適用所有的字符串和整數(shù),具體情況參考源碼實(shí)現(xiàn)。
根據(jù) python 官方文檔, id() 函數(shù)解釋如下
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() 函數(shù)返回的是動(dòng)態(tài)創(chuàng)建的字符串,它的內(nèi)存地址不是預(yù)知的。
而 tt2 = 'TT'; tt3 = 'TT'; 這種, python 解釋器只會(huì)保存第一個(gè) ‘TT’ 字符串,第二個(gè) ‘TT’ 被引向前面那個(gè)。因此它們的 id() 結(jié)果相同。改變 tt2 或 tt3 將導(dǎo)致新的字符串產(chǎn)生,而不會(huì)改變 ‘TT’ 內(nèi)容。
這個(gè)問題看似簡(jiǎn)單,但是卻觸及到了計(jì)算機(jī)的底層?。?!
>>>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) 函數(shù)是返回對(duì)象 object 位于內(nèi)存中的地址。
但是,根據(jù)《深入理解計(jì)算機(jī)系統(tǒng)》對(duì) 信息 的定義, 你會(huì)認(rèn)識(shí)到 python 文檔一貫輕佻的調(diào)性,這里沒有提 上下文, 沒有提對(duì)象的生命周期,這是不嚴(yán)謹(jǐn)?shù)?。因?yàn)闆]有提到重要的上下文關(guān)系。
我做了兩個(gè)腳本:
test1.py 內(nèi)容如下:
print(__name__)
test1 = input('ttt>>>').strip()
print(test1)
print(id(test1))
test2 = 'TT'
print(id(test2))
test2.py 內(nèi)容如下:
test3 = 'TT'
print(__name__)
print(id(test3))
運(yùn)行第一個(gè)腳本,顯示主程是 __main__,結(jié)果,你會(huì)發(fā)現(xiàn)和題主的腳本是一樣的,兩個(gè) id 是不一樣的。
運(yùn)行第二個(gè)腳本,顯示主程是 __main__,結(jié)果,你會(huì)發(fā)現(xiàn)這里的 id 和第一也是不一樣的。
也就是說,對(duì)象的對(duì)應(yīng)的 內(nèi)存地址 是不一樣的,因?yàn)椋?strong>上下文 ,或者說程序的生命周期不一樣。
更直觀點(diǎn),你運(yùn)行第一個(gè)腳本很多遍,每次 id 顯示的內(nèi)容幾乎都是不一樣的。
運(yùn)行第二個(gè)腳本也是如此。
至于為什么我用 幾乎這個(gè)詞,還是留給你們自行查資料把。
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國成功上市,融資1
北大課工場(chǎng)是北京大學(xué)校辦產(chǎn)業(yè)為響應(yīng)國家深化產(chǎn)教融合/校企合作的政策,積極推進(jìn)“中國制造2025”,實(shí)現(xiàn)中華民族偉大復(fù)興的升級(jí)產(chǎn)業(yè)鏈。利用北京大學(xué)優(yōu)質(zhì)教育資源及背
博為峰,中國職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國Software AG 技術(shù)顧問,美國Dachieve 系統(tǒng)架構(gòu)師,美國AngelEngineers Inc. 系統(tǒng)架構(gòu)師。