日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁(yè) > 科技  > 軟件

Python 對(duì)象有哪幾種,我們可以從哪些角度進(jìn)行分類呢?

來(lái)源: 責(zé)編: 時(shí)間:2024-05-11 09:20:49 194觀看
導(dǎo)讀楔子在程序開(kāi)發(fā)中,我們每時(shí)每刻都在創(chuàng)建對(duì)象,那到底什么是對(duì)象呢?其實(shí)一個(gè)對(duì)象就是一片被分配的內(nèi)存空間,空間可以是連續(xù)的,也可以是不連續(xù)的。然后空間里面存儲(chǔ)了指定的數(shù)據(jù),并提供了操作數(shù)據(jù)的一些功能方法。而按照是否可

楔子

li828資訊網(wǎng)——每日最新資訊28at.com

li828資訊網(wǎng)——每日最新資訊28at.com

在程序開(kāi)發(fā)中,我們每時(shí)每刻都在創(chuàng)建對(duì)象,那到底什么是對(duì)象呢?li828資訊網(wǎng)——每日最新資訊28at.com

其實(shí)一個(gè)對(duì)象就是一片被分配的內(nèi)存空間,空間可以是連續(xù)的,也可以是不連續(xù)的。然后空間里面存儲(chǔ)了指定的數(shù)據(jù),并提供了操作數(shù)據(jù)的一些功能方法。而按照是否可變和內(nèi)存大小是否固定,我們可以將對(duì)象進(jìn)行如下分類。li828資訊網(wǎng)——每日最新資訊28at.com

  • 可變對(duì)象和不可變對(duì)象;
  • 定長(zhǎng)對(duì)象和變長(zhǎng)對(duì)象;

下面來(lái)詳細(xì)解釋一下。li828資訊網(wǎng)——每日最新資訊28at.com

li828資訊網(wǎng)——每日最新資訊28at.com

可變對(duì)象和不可變對(duì)象

li828資訊網(wǎng)——每日最新資訊28at.com

li828資訊網(wǎng)——每日最新資訊28at.com

不可變對(duì)象一旦創(chuàng)建,其內(nèi)存中存儲(chǔ)的值就不可以再修改了。如果想修改,只能創(chuàng)建一個(gè)新的對(duì)象,然后讓變量指向新的對(duì)象,所以前后的地址會(huì)發(fā)生改變。而可變對(duì)象在創(chuàng)建之后,其存儲(chǔ)的值可以動(dòng)態(tài)修改。li828資訊網(wǎng)——每日最新資訊28at.com

像整數(shù)就是一個(gè)不可變對(duì)象。li828資訊網(wǎng)——每日最新資訊28at.com

>>> a = 666>>> id(a)2230564873872>>> a += 1>>> id(a)2230564873808

我們看到執(zhí)行 a += 1 操作之后,前后地址發(fā)生了變化,所以整數(shù)不支持本地修改,因此是一個(gè)不可變對(duì)象;li828資訊網(wǎng)——每日最新資訊28at.com

圖片圖片li828資訊網(wǎng)——每日最新資訊28at.com

原來(lái) a = 666,而我們說(shuō)操作一個(gè)變量等于操作這個(gè)變量指向的內(nèi)存,所以 a+=1 會(huì)將 a 指向的整數(shù)對(duì)象 666 和 1 進(jìn)行加法運(yùn)算,得到 667。因此會(huì)開(kāi)辟新的空間來(lái)存儲(chǔ) 667,然后讓 a 指向這片新的空間。至于原來(lái)的 666 所占的空間怎么辦,解釋器會(huì)看它的引用計(jì)數(shù),如果不為 0 代表還有變量引用(指向)它,如果為 0 證明沒(méi)有變量引用了,所以會(huì)被回收。li828資訊網(wǎng)——每日最新資訊28at.com

關(guān)于引用計(jì)數(shù),我們后面會(huì)詳細(xì)說(shuō),目前只需要知道當(dāng)一個(gè)對(duì)象被一個(gè)變量引用的時(shí)候,那么該對(duì)象的引用計(jì)數(shù)就會(huì)加 1。有幾個(gè)變量引用,那么它的引用計(jì)數(shù)就是幾。li828資訊網(wǎng)——每日最新資訊28at.com

li828資訊網(wǎng)——每日最新資訊28at.com

除了整數(shù)之外,浮點(diǎn)數(shù)、字符串、布爾值等等,都是不可變對(duì)象,它們的值不能本地修改。li828資訊網(wǎng)——每日最新資訊28at.com

然后是可變對(duì)象,像列表、字典、集合等都是可變對(duì)象,它們支持動(dòng)態(tài)修改。li828資訊網(wǎng)——每日最新資訊28at.com

這里先多提一句,Python 的對(duì)象本質(zhì)上就是 C 中 malloc 函數(shù)為結(jié)構(gòu)體實(shí)例在堆區(qū)申請(qǐng)的一塊內(nèi)存。Python 的任何對(duì)象在 C 中都會(huì)對(duì)應(yīng)一個(gè)結(jié)構(gòu)體,這個(gè)結(jié)構(gòu)體除了存放具體的值之外,還存放了一些額外的信息,這個(gè)我們?cè)诤罄m(xù)剖析內(nèi)置對(duì)象的時(shí)候會(huì)細(xì)說(shuō)。li828資訊網(wǎng)——每日最新資訊28at.com

在上一篇文章中我們說(shuō)到,列表、元組、集合這些容器的內(nèi)部存儲(chǔ)的不是具體的對(duì)象,而是對(duì)象的指針。比如:lst = [1, 2, 3],你以為列表存儲(chǔ)的是三個(gè)整數(shù)對(duì)象嗎?其實(shí)不是的,它存儲(chǔ)的是三個(gè)整數(shù)對(duì)象的指針,當(dāng)我們使用 lst[0] 的時(shí)候,拿到的是一個(gè)指針,但是操作(比如 print)的時(shí)候會(huì)自動(dòng)操作指針指向的內(nèi)存。li828資訊網(wǎng)——每日最新資訊28at.com

因?yàn)?Python 底層是 C 來(lái)實(shí)現(xiàn)的,所以列表的實(shí)現(xiàn)必然要借助 C 的數(shù)組。可 C 數(shù)組里面的元素的類型必須一致,但列表卻可以存放任意的元素,因此從這個(gè)角度上講,列表里面的元素就不可能是對(duì)象,因?yàn)椴煌膶?duì)象在底層對(duì)應(yīng)的結(jié)構(gòu)體是不同的,所以元素只能是指針。li828資訊網(wǎng)——每日最新資訊28at.com

可能有人又好奇了,不同對(duì)象的指針也是不同的啊,是的,但 C 指針是可以轉(zhuǎn)化的。Python 底層將所有對(duì)象的指針,都轉(zhuǎn)成了 PyObject 類型的指針,這樣不就是同一種類型的指針了嗎?關(guān)于這個(gè) PyObject,它是我們后面要剖析的重中之重,貫穿了整個(gè)系列。不過(guò)目前只需要知道列表(還有其它容器)存儲(chǔ)的元素、以及 Python 的變量,它們都是一個(gè)泛型指針 PyObject *。li828資訊網(wǎng)——每日最新資訊28at.com

>>> lst = [1, 2, 3]>>> id(lst)2287192570048>>> lst.append(4)>>> lst[1, 2, 3, 4]>>> id(lst)2287192570048

我們看到列表在添加元素的時(shí)候,前后地址并沒(méi)有改變。列表在 C 中是通過(guò) PyListObject 結(jié)構(gòu)體實(shí)現(xiàn)的,我們?cè)诮榻B列表的時(shí)候會(huì)細(xì)說(shuō)。這個(gè) PyListObject 內(nèi)部除了一些基本信息之外,還維護(hù)了一個(gè) PyObject 的二級(jí)指針,指向了 PyObject * 類型的數(shù)組的首元素。li828資訊網(wǎng)——每日最新資訊28at.com

圖片圖片li828資訊網(wǎng)——每日最新資訊28at.com

顯然圖中的指針數(shù)組用來(lái)存儲(chǔ)具體的對(duì)象的指針,每一個(gè)指針都指向了相應(yīng)的對(duì)象(這里是整數(shù)對(duì)象)。li828資訊網(wǎng)——每日最新資訊28at.com

然后我們還可以看到一個(gè)現(xiàn)象,那就是列表在底層是分開(kāi)存儲(chǔ)的,因?yàn)?PyListObject 結(jié)構(gòu)體實(shí)例并沒(méi)有存儲(chǔ)相應(yīng)的指針數(shù)組,而是存儲(chǔ)了一個(gè)二級(jí)指針。顯然添加、刪除、修改元素等操作,都是通過(guò)這個(gè)二級(jí)指針來(lái)間接操作指針數(shù)組。li828資訊網(wǎng)——每日最新資訊28at.com

因?yàn)橐粋€(gè)對(duì)象一旦被創(chuàng)建(任何語(yǔ)言都是如此),那么它在內(nèi)存中的大小就不可以變了。所以這就意味著那些可以容納可變長(zhǎng)度數(shù)據(jù)的可變對(duì)象,要在內(nèi)部維護(hù)一個(gè)指針,指針指向一片內(nèi)存區(qū)域,該區(qū)域存放具體的數(shù)據(jù)。如果空間不夠了,那就申請(qǐng)一片更大的內(nèi)存區(qū)域,然后將元素依次拷貝過(guò)去,再讓指針指向新的內(nèi)存區(qū)域。而列表的底層也是這么做的,其內(nèi)部并沒(méi)有直接存儲(chǔ)具體的指針數(shù)組,而是存儲(chǔ)了指向指針數(shù)組首元素的二級(jí)指針。li828資訊網(wǎng)——每日最新資訊28at.com

那么問(wèn)題來(lái)了,為什么要這么做?li828資訊網(wǎng)——每日最新資訊28at.com

其實(shí)很好理解,遵循這樣的規(guī)則可以使通過(guò)指針維護(hù)對(duì)象的工作變得非常簡(jiǎn)單。一旦允許對(duì)象的大小可在運(yùn)行期改變,那么我們就要考慮如下場(chǎng)景。li828資訊網(wǎng)——每日最新資訊28at.com

在內(nèi)存中有對(duì)象 A,并且其后面緊跟著對(duì)象 B。如果在運(yùn)行的某個(gè)時(shí)候,A 的大小增大了,這就意味著必須將 A 整個(gè)移動(dòng)到內(nèi)存中的其他位置,否則 A 增大的部分會(huì)覆蓋掉原本屬于 B 的數(shù)據(jù)。但要將 A 移動(dòng)到內(nèi)存的其他位置,那么所有指向 A 的指針就必須立即得到更新。可想而知這樣的工作是多么的繁瑣,因此通過(guò)在可變對(duì)象的內(nèi)部維護(hù)一個(gè)指針就變得簡(jiǎn)單多了。li828資訊網(wǎng)——每日最新資訊28at.com

li828資訊網(wǎng)——每日最新資訊28at.com

定長(zhǎng)對(duì)象和變長(zhǎng)對(duì)象

li828資訊網(wǎng)——每日最新資訊28at.com

li828資訊網(wǎng)——每日最新資訊28at.com

所謂定長(zhǎng)和變長(zhǎng),取決于對(duì)象所占的內(nèi)存大小是否固定,舉個(gè)例子。li828資訊網(wǎng)——每日最新資訊28at.com

>>> import sys>>> sys.getsizeof("")41>>> sys.getsizeof("hello")46>>> sys.getsizeof("hello world")52>>> sys.getsizeof(1.0)24>>> sys.getsizeof(3.14)24>>> sys.getsizeof((2 << 30) + 3.14)24

我們看到字符串的長(zhǎng)度不同,所占的內(nèi)存也不同,像這種內(nèi)存大小不固定的對(duì)象,我們稱之為變長(zhǎng)對(duì)象;而浮點(diǎn)數(shù)所占的內(nèi)存都是一樣的,像這種內(nèi)存大小固定的對(duì)象,我們稱之為定長(zhǎng)對(duì)象。li828資訊網(wǎng)——每日最新資訊28at.com

至于 Python 如何計(jì)算對(duì)象所占的內(nèi)存,我們?cè)谄饰鼍唧w對(duì)象的時(shí)候會(huì)說(shuō),因?yàn)檫@涉及到底層對(duì)應(yīng)的結(jié)構(gòu)體。li828資訊網(wǎng)——每日最新資訊28at.com

所以變長(zhǎng)對(duì)象的特點(diǎn)是:同一個(gè)類型的實(shí)例對(duì)象,如果值不同,那么占用的內(nèi)存大小不同。像字符串、列表、元組、字典等,它們毫無(wú)疑問(wèn)都是變長(zhǎng)對(duì)象。值得一提的是,整數(shù)也是變長(zhǎng)對(duì)象,因?yàn)?Python 整數(shù)的值在底層是通過(guò)數(shù)組維護(hù)的,后續(xù)介紹整數(shù)實(shí)現(xiàn)的時(shí)候再聊。li828資訊網(wǎng)——每日最新資訊28at.com

而定長(zhǎng)對(duì)象的特點(diǎn)是:同一個(gè)類型的實(shí)例對(duì)象,不管值是多少,占用的內(nèi)存大小始終是固定的,比如浮點(diǎn)數(shù)。因?yàn)?Python 的浮點(diǎn)數(shù)的值在 C 中是通過(guò)一個(gè) double 來(lái)維護(hù)的。而 C 里面值的類型一旦確定,大小就不變了,所以 Python 浮點(diǎn)數(shù)的大小也是不變的。li828資訊網(wǎng)——每日最新資訊28at.com

但既然類型固定,大小固定,那么范圍肯定是有限的。所以當(dāng)浮點(diǎn)數(shù)不斷增大,會(huì)犧牲精度來(lái)進(jìn)行存儲(chǔ)。li828資訊網(wǎng)——每日最新資訊28at.com

圖片圖片li828資訊網(wǎng)——每日最新資訊28at.com

如果實(shí)在過(guò)大,則拋出 OverFlowError。li828資訊網(wǎng)——每日最新資訊28at.com

圖片圖片li828資訊網(wǎng)——每日最新資訊28at.com

當(dāng)然除了浮點(diǎn)數(shù)之外,布爾值、復(fù)數(shù)等也屬于定長(zhǎng)對(duì)象,它們占用的內(nèi)存大小是固定的。li828資訊網(wǎng)——每日最新資訊28at.com

li828資訊網(wǎng)——每日最新資訊28at.com

小結(jié)

li828資訊網(wǎng)——每日最新資訊28at.com

li828資訊網(wǎng)——每日最新資訊28at.com

以上我們就分析了對(duì)象的種類,對(duì)象可以被分為可變對(duì)象和不可變對(duì)象,以及變長(zhǎng)對(duì)象和定長(zhǎng)對(duì)象。li828資訊網(wǎng)——每日最新資訊28at.com

  • 不可變對(duì)象:對(duì)象不支持本地修改;
  • 可變對(duì)象:對(duì)象支持本地修改;
  • 變長(zhǎng)對(duì)象:對(duì)象維護(hù)的值不同,占用的內(nèi)存大小也不同;
  • 定長(zhǎng)對(duì)象:占用的內(nèi)存大小始終固定;

本文參考自:li828資訊網(wǎng)——每日最新資訊28at.com

  • 陳儒《Python 源碼剖析》

本文鏈接:http://www.www897cc.com/showinfo-26-87986-0.htmlPython 對(duì)象有哪幾種,我們可以從哪些角度進(jìn)行分類呢?

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 在Go語(yǔ)言中,這樣使用Json的

下一篇: 一篇文章徹底搞懂Arthas的原理,你學(xué)會(huì)了嗎?

標(biāo)簽:
  • 熱門焦點(diǎn)
  • 影音體驗(yàn)是真的強(qiáng) 簡(jiǎn)單聊聊iQOO Pad

    大公司的好處就是產(chǎn)品線豐富,非常細(xì)分化的東西也能給你做出來(lái),例如早先我們看到了新的vivo Pad2,之后我們又在iQOO Neo8 Pro的發(fā)布會(huì)上看到了iQOO的首款平板產(chǎn)品iQOO Pad。雖
  • Flowable工作流引擎的科普與實(shí)踐

    一.引言當(dāng)我們?cè)谌粘9ぷ骱蜆I(yè)務(wù)中需要進(jìn)行各種審批流程時(shí),可能會(huì)面臨一系列技術(shù)和業(yè)務(wù)上的挑戰(zhàn)。手動(dòng)處理這些審批流程可能會(huì)導(dǎo)致開(kāi)發(fā)成本的增加以及業(yè)務(wù)復(fù)雜度的上升。在這
  • 如何通過(guò)Python線程池實(shí)現(xiàn)異步編程?

    線程池的概念和基本原理線程池是一種并發(fā)處理機(jī)制,它可以在程序啟動(dòng)時(shí)創(chuàng)建一組線程,并將它們置于等待任務(wù)的狀態(tài)。當(dāng)任務(wù)到達(dá)時(shí),線程池中的某個(gè)線程會(huì)被喚醒并執(zhí)行任務(wù),執(zhí)行完任
  • 三分鐘白話RocketMQ系列—— 如何發(fā)送消息

    我們知道RocketMQ主要分為消息 生產(chǎn)、存儲(chǔ)(消息堆積)、消費(fèi) 三大塊領(lǐng)域。那接下來(lái),我們白話一下,RocketMQ是如何發(fā)送消息的,揭秘消息生產(chǎn)全過(guò)程。注意,如果白話中不小心提到相關(guān)代
  • JVM優(yōu)化:實(shí)戰(zhàn)OutOfMemoryError異常

    一、Java堆溢出堆內(nèi)存中主要存放對(duì)象、數(shù)組等,只要不斷地創(chuàng)建這些對(duì)象,并且保證 GC Roots 到對(duì)象之間有可達(dá)路徑來(lái)避免垃 圾收集回收機(jī)制清除這些對(duì)象,當(dāng)這些對(duì)象所占空間超過(guò)
  • 自律,給不了Keep自由!

    來(lái)源 | 互聯(lián)網(wǎng)品牌官作者 | 李大為編排 | 又耳 審核 | 谷曉輝自律能不能給用戶自由暫時(shí)不好說(shuō),但大概率不能給Keep自由。近日,全球最大的在線健身平臺(tái)Keep正式登陸港交所,努力
  • 新電商三兄弟,“抖快紅”成團(tuán)!

    來(lái)源:價(jià)值研究所作 者:Hernanderz 隨著內(nèi)容電商的概念興起,抖音、快手、小紅書(shū)組成的&ldquo;新電商三兄弟&rdquo;成為業(yè)內(nèi)一股不可忽視的勢(shì)力,給阿里、京東、拼多多帶去了巨大壓
  • 微軟發(fā)布Windows 11新版 引入全新任務(wù)欄狀態(tài)

    近日,微軟發(fā)布了Windows 11新版,而B(niǎo)uild 22563更新主要引入了幾周前曝光的平板模式任務(wù)欄等,系統(tǒng)更流暢了。更新中,Windows 11加入了專門針對(duì)平板優(yōu)化的任務(wù)欄
  • 由于成本持續(xù)增加,筆記本產(chǎn)品價(jià)格預(yù)計(jì)將明顯上漲

    根據(jù)知情人士透露,由于材料、物流等成本持續(xù)增加,筆記本產(chǎn)品價(jià)格預(yù)計(jì)將在2021年下半年有明顯上漲。進(jìn)入6月下旬以來(lái),全球半導(dǎo)體芯片缺貨情況加劇,顯卡、處理器
Top 主站蜘蛛池模板: 钟祥市| 建瓯市| 弋阳县| 城市| 宁河县| 陇西县| 华安县| 壤塘县| 黄梅县| 镇雄县| 和龙市| 收藏| 石阡县| 贡山| 乌海市| 聂荣县| 柏乡县| 玉门市| 洪雅县| 冕宁县| 乳山市| 东港市| 余江县| 营口市| 保德县| 台北县| 永清县| 仙居县| 古田县| 沅江市| 常山县| 和硕县| 博白县| 中西区| 崇信县| 辽源市| 彩票| 庄浪县| 赤壁市| 老河口市| 咸丰县|