Python小数据池
- 一. id is ==
- 二. 代碼塊
- 三. 小數(shù)據(jù)池
- 四. 總結(jié)
一,id,is,==
在Python中,id是什么?id是內(nèi)存地址,那就有人問了,什么是內(nèi)存地址呢? 你只要?jiǎng)?chuàng)建一個(gè)數(shù)據(jù)(對(duì)象)那么都會(huì)在內(nèi)存中開辟一個(gè)空間,將這個(gè)數(shù)據(jù)臨時(shí)加在到內(nèi)存中,那么這個(gè)空間是有一個(gè)唯一標(biāo)識(shí)的,就好比是身份證號(hào),標(biāo)識(shí)這個(gè)空間的叫做內(nèi)存地址,也就是這個(gè)數(shù)據(jù)(對(duì)象)的id,那么你可以利用id()去獲取這個(gè)數(shù)據(jù)的內(nèi)存地址:
name = '太白' print(id(name)) # 1585831283968那么 is 是什么? == 又是什么?
== 是比較的兩邊的數(shù)值是否相等,而 is 是比較的兩邊的內(nèi)存地址是否相等。 如果內(nèi)存地址相等,那么這兩邊其實(shí)是指向同一個(gè)內(nèi)存地址。
可以說如果內(nèi)存地址相同,那么值肯定相同,但是如果值相同,內(nèi)存地址不一定相同。
二,代碼塊。
根據(jù)官網(wǎng)提示我們可以獲知:
根據(jù)提示我們從官方文檔找到了這樣的說法: A Python program is constructed from code blocks. A block is a piece of Python program text that is executed as a unit. The following are blocks: a module, a function body, and a class definition. Each command typed interactively is a block. A script file (a file given as standard input to the interpreter or specified as a command line argument to the interpreter) is a code block. A script command (a command specified on the interpreter command line with the ‘-c‘ option) is a code block. The string argument passed to the built-in functions eval() and exec() is a code block. A code block is executed in an execution frame. A frame contains some administrative information (used for debugging) and determines where and how execution continues after the code block’s execution has completed. View Code上面的主要意思是:
Python程序是由代碼塊構(gòu)造的。塊是一個(gè)python程序的文本,他是作為一個(gè)單元執(zhí)行的。
代碼塊:一個(gè)模塊,一個(gè)函數(shù),一個(gè)類,一個(gè)文件等都是一個(gè)代碼塊。
而作為交互方式輸入的每個(gè)命令都是一個(gè)代碼塊。
什么叫交互方式?就是咱們?cè)赾md中進(jìn)入Python解釋器里面,每一行代碼都是一個(gè)代碼塊,例如:
而對(duì)于一個(gè)文件中的兩個(gè)函數(shù),也分別是兩個(gè)不同的代碼塊:
那么,可能有的同學(xué)還有一些不理解代碼塊,可以這樣解釋:我們都上過學(xué)對(duì)吧,你們?cè)诔踔械臅r(shí)候,有沒有過值周?就以一個(gè)班的學(xué)生用一星期的時(shí)間打掃整個(gè)學(xué)校,再比如有沒有運(yùn)動(dòng)會(huì),無論是值周,還是運(yùn)動(dòng)會(huì),還是組織什么活動(dòng),都是以什么為單位呢?對(duì),都是以班級(jí)為單位,那么咱們學(xué)生就好比是代碼,班級(jí)就好比是代碼塊,我們想讓代碼運(yùn)行起來,必須依靠班級(jí)去執(zhí)行,也就是代碼塊。
OK,那么現(xiàn)在我們了解了代碼塊,這和小數(shù)據(jù)池有什么關(guān)系呢?且聽下面分析。
代碼塊的緩存機(jī)制
前提條件:在同一個(gè)代碼塊內(nèi)。
機(jī)制內(nèi)容:Python在執(zhí)行同一個(gè)代碼塊的初始化對(duì)象的命令時(shí),會(huì)檢查是否其值是否已經(jīng)存在,如果存在,會(huì)將其重用。換句話說:執(zhí)行同一個(gè)代碼塊時(shí),遇到初始化對(duì)象的命令時(shí),他會(huì)將初始化的這個(gè)變量與值存儲(chǔ)在一個(gè)字典中,在遇到新的變量時(shí),會(huì)先在字典中查詢記錄,如果有同樣的記錄那么它會(huì)重復(fù)使用這個(gè)字典中的之前的這個(gè)值。所以在你給出的例子中,文件執(zhí)行時(shí)(同一個(gè)代碼塊)會(huì)把i1、i2兩個(gè)變量指向同一個(gè)對(duì)象,滿足緩存機(jī)制則他們?cè)趦?nèi)存中只存在一個(gè),即:id相同。
適用對(duì)象:?int(float),str,bool。
對(duì)象的具體細(xì)則:(了解)
int(float):任何數(shù)字在同一代碼塊下都會(huì)復(fù)用。
bool:True和False在字典中會(huì)以1,0方式存在,并且復(fù)用。
str:幾乎所有的字符串都會(huì)符合緩存機(jī)制,具體規(guī)定如下(了解即可!):
1,非乘法得到的字符串都滿足代碼塊的緩存機(jī)制:
s1 = '太白@!#*ewq' s2 = '太白@!#*ewq' print(s1 is s2) # True2,乘法得到的字符串分兩種情況:
2.1 乘數(shù)為1時(shí),任何字符串滿足代碼塊的緩存機(jī)制:
b1 = '太白@5847395QQ0743895*&^%$#((&_+(())' *1 a1 = '太白@5847395QQ0743895*&^%$#((&_+(())' *1print(a1 is b1) # True2.2 乘數(shù)>=2時(shí):僅含大小寫字母,數(shù)字,下劃線,總長(zhǎng)度<=20,滿足代碼塊的緩存機(jī)制:
s1 = 'old_' * 5 s2 = 'old_' * 5 print(s1 is s2) # True?優(yōu)點(diǎn):能夠提高一些字符串,整數(shù)處理人物在時(shí)間和空間上的性能;需要值相同的字符串,整數(shù)的時(shí)候,直接從‘字典’中取出復(fù)用,避免頻繁的創(chuàng)建和銷毀,提升效率,節(jié)約內(nèi)存。
?三,小數(shù)據(jù)池
小數(shù)據(jù)池,不同代碼塊的緩存機(jī)制,也稱為小整數(shù)緩存機(jī)制,或者稱為駐留機(jī)制等等,博主認(rèn)為,只要你在網(wǎng)上查到的這些名字其實(shí)說的都是一個(gè)意思,叫什么因人而異。
那么到底什么是小數(shù)據(jù)池?他有什么作用呢?
前提條件:在不同一個(gè)代碼塊內(nèi)。
機(jī)制內(nèi)容:官方對(duì)于整數(shù),字符串的小數(shù)據(jù)池是這么說的:
對(duì)于整數(shù),Python官方文檔中這么說: The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object. So it should be possible to change the value of 1. I suspect the behaviour of Python in this case is undefined.對(duì)于字符串: Incomputer science, string interning is a method of storing only onecopy of each distinct string value, which must be immutable. Interning strings makes some stringprocessing tasks more time- or space-efficient at the cost of requiring moretime when the string is created or interned. The distinct values are stored ina string intern pool. –引自維基百科 View Code來,我給你們翻譯并匯總一下,這個(gè)表達(dá)的意思就是:
Python自動(dòng)將-5~256的整數(shù)進(jìn)行了緩存,當(dāng)你將這些整數(shù)賦值給變量時(shí),并不會(huì)重新創(chuàng)建對(duì)象,而是使用已經(jīng)創(chuàng)建好的緩存對(duì)象。
python會(huì)將一定規(guī)則的字符串在字符串駐留池中,創(chuàng)建一份,當(dāng)你將這些字符串賦值給變量時(shí),并不會(huì)重新創(chuàng)建對(duì)象, 而是使用在字符串駐留池中創(chuàng)建好的對(duì)象。
其實(shí),無論是緩存還是字符串駐留池,都是python做的一個(gè)優(yōu)化,就是將~5-256的整數(shù),和一定規(guī)則的字符串,放在一個(gè)‘池’(容器,或者字典)中,無論程序中那些變量指向這些范圍內(nèi)的整數(shù)或者字符串,那么他直接在這個(gè)‘池’中引用,言外之意,就是內(nèi)存中之創(chuàng)建一個(gè)。
適用對(duì)象:?int(float),str,bool?
對(duì)象的具體細(xì)則:(了解即可)
int:那么大家都知道對(duì)于整數(shù)來說,小數(shù)據(jù)池的范圍是-5~256 ,如果多個(gè)變量都是指向同一個(gè)(在這個(gè)范圍內(nèi)的)數(shù)字,他們?cè)趦?nèi)存中指向的都是一個(gè)內(nèi)存地址。
那么對(duì)于字符串的規(guī)定呢?
str:字符串要從下面這幾個(gè)大方向討論(了解即可!):
1,字符串的長(zhǎng)度為0或者1,默認(rèn)都采用了駐留機(jī)制(小數(shù)據(jù)池)。
2,字符串的長(zhǎng)度>1,且只含有大小寫字母,數(shù)字,下劃線時(shí),才會(huì)默認(rèn)駐留。
?
3,用乘法得到的字符串,分兩種情況。
3.1 乘數(shù)為1時(shí):
僅含大小寫字母,數(shù)字,下劃線,默認(rèn)駐留。
含其他字符,長(zhǎng)度<=1,默認(rèn)駐留。
含其他字符,長(zhǎng)度>1,默認(rèn)駐留。
3.2 乘數(shù)>=2時(shí):
僅含大小寫字母,數(shù)字,下劃線,總長(zhǎng)度<=20,默認(rèn)駐留。
4,指定駐留。
from sys import intern a = intern('hello!@'*20) b = intern('hello!@'*20) print(a is b) #指定駐留是你可以指定任意的字符串加入到小數(shù)據(jù)池中,讓其只在內(nèi)存中創(chuàng)建一個(gè)對(duì)象,多個(gè)變量都是指向這一個(gè)字符串。滿足以上字符串的規(guī)則時(shí),就符合小數(shù)據(jù)池的概念。
bool值就是True,False,無論你創(chuàng)建多少個(gè)變量指向True,False,那么他在內(nèi)存中只存在一個(gè)。
看一下用了小數(shù)據(jù)池(駐留機(jī)制)的效率有多高:
顯而易見,節(jié)省大量?jī)?nèi)存在字符串比較時(shí),非駐留比較效率o(n),駐留時(shí)比較效率o(1)。
優(yōu)點(diǎn):能夠提高一些字符串,整數(shù)處理人物在時(shí)間和空間上的性能;需要值相同的字符串,整數(shù)的時(shí)候,直接從‘池’里拿來用,避免頻繁的創(chuàng)建和銷毀,提升效率,節(jié)約內(nèi)存
四,小結(jié)。
如果在同一代碼塊下,則采用同一代碼塊下的換緩存機(jī)制。
如果是不同代碼塊,則采用小數(shù)據(jù)池的駐留機(jī)制。
# pycharm 通過運(yùn)行文件的方式執(zhí)行下列代碼: 這是在同一個(gè)文件下也就是同一代碼塊下,采用同一代碼塊下的緩存機(jī)制。 i1 = 1000 i2 = 1000 print(i1 is i2) # 結(jié)果為True 因?yàn)榇a塊下的緩存機(jī)制適用于所有數(shù)字 通過交互方式中執(zhí)行下面代碼: # 這是不同代碼塊下,則采用小數(shù)據(jù)池的駐留機(jī)制。 >>> i1 = 1000 >>> i2 = 1000 >>> print(i1 is i2) False # 不同代碼塊下的小數(shù)據(jù)池駐留機(jī)制 數(shù)字的范圍只是-5~256.更多驗(yàn)證:
# 雖然在同一個(gè)文件中,但是函數(shù)本身就是代碼塊,所以這是在兩個(gè)不同的代碼塊下,不滿足小數(shù)據(jù)池(駐存機(jī)制),則指向兩個(gè)不同的地址。 def func():i1 = 1000print(id(i1)) # 2288555806672def func2():i1 = 1000print(id(i1)) # 2288557317392 func() func2()?
本文大量引用和參考鏈接如下:?
https://zhidao.baidu.com/question/494120409773699052.html??
http://mini.eastday.com/bdmip/180405084648167.html
轉(zhuǎn)載自:
https://www.cnblogs.com/jin-xin/articles/9439483.html
轉(zhuǎn)載于:https://www.cnblogs.com/bqwzx/p/11013636.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的Python小数据池的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 谷歌浏览器怎么登录及开启同步功能
- 下一篇: python NoSuchElement