<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          為什么 Python 不用聲明類型?

          共 2513字,需瀏覽 6分鐘

           ·

          2021-04-20 02:20

          作者:編程指北

          來(lái)源:編程指北

          變量為什么需要類型?

          這個(gè)問(wèn)題點(diǎn)像手機(jī)為什么叫手機(jī),電腦為什么叫電腦,這種“日用而不知”的感覺(jué)。

          為什么有些語(yǔ)言需要申明類型,而有些語(yǔ)言卻不需要申明類型?

          前者如 C/C++、Java,后者有 Python、JS 。

          首先,在討論為什么需要類型之前,先聊聊類型。

          一、 類型

          我們都知道,不管是中文、英文還是編程語(yǔ)言,都具有語(yǔ)法,語(yǔ)法規(guī)定了詞怎么組成句子是符合規(guī)范的。

          int a = 10;是可以的,但是a int = 10; 卻不符合 C 語(yǔ)法規(guī)范。

          10 + 10 是正確的,但是10 + “hello” 卻是一個(gè)無(wú)效的表達(dá)式,但是該怎么判定呢?

          答案就是「類型系統(tǒng)」,類型系統(tǒng)可以構(gòu)建起一套判斷表達(dá)式是否合法的規(guī)則。

          對(duì)于每個(gè)變量都賦予一個(gè)類型,對(duì)于每種類型都定義了一組操作集合,而變量作為類型的實(shí)例,自然的繼承了這些操作。

          比如我們可以規(guī)定int + int、string + string 是合法的操作,直接禁止int + string等操作。

          通過(guò)顯示的將變量賦予類型,我們便可以在編譯時(shí)去檢查是否合法。

          二、 變量

          之前我在指針的那篇文章種說(shuō)到:變量名是變量地址的符號(hào)化,變量名是為了讓我們編程時(shí)更加方便,對(duì)人友好,可計(jì)算機(jī)可不認(rèn)識(shí)什么變量 a,它只知道地址和指令。

          所以當(dāng)你去查看 C 語(yǔ)言編譯后的匯編代碼,就會(huì)發(fā)現(xiàn)變量名消失了,取而代之的是一串串抽象的地址。

          可以認(rèn)為,編譯器會(huì)自動(dòng)維護(hù)一個(gè)映射,將我們程序中的變量名轉(zhuǎn)換為變量所對(duì)應(yīng)的地址,然后再對(duì)這個(gè)地址去進(jìn)行讀寫操作。

          三、類型規(guī)定了什么?

          我個(gè)人覺(jué)得類型首先是定義了一組操作,這是語(yǔ)法層面。

          那所有的高級(jí)語(yǔ)言最后都會(huì)變成機(jī)器語(yǔ)言執(zhí)行(解釋型除外),再高級(jí)一點(diǎn),那就是匯編,我們知道匯編語(yǔ)言是由一條條指令構(gòu)成的。

          而對(duì)于任何一條指令,最重要的有兩點(diǎn):數(shù)據(jù)的長(zhǎng)度、數(shù)據(jù)在哪。

          比如mov dest,src將一個(gè)字節(jié)從源地址 src 傳送到目的地址 dest。

          實(shí)際上,數(shù)據(jù)在哪就是地址,數(shù)據(jù)長(zhǎng)度其實(shí)某方面就是取決于類型。

          也正是這樣,我之前在指針那篇文章中提到:指針的本質(zhì)就是存儲(chǔ)別的變量的地址,那么指針的類型是干什么用的呢?

          是的,就是去訪問(wèn)指針?biāo)赶虻牡刂返臅r(shí)候,指針的類型和指針的值(變量地址),提供了一條匯編指令最關(guān)鍵的兩點(diǎn):數(shù)據(jù)的長(zhǎng)度和數(shù)據(jù)地址。

          所以,類型除了提供語(yǔ)法檢查以外,還能夠明確變量所占據(jù)的內(nèi)存空間。

          同樣也是規(guī)定了對(duì)字節(jié)的解釋方式,同樣 4 個(gè)byte,按照 int 和 float 類型解釋得到的值完全不同。

          更為本質(zhì)的是,最終執(zhí)行指令的 CPU 是區(qū)分了數(shù)據(jù)的類型的,不同的類型用不同的運(yùn)算器,比如有 CPU 整形運(yùn)算和 CPU 浮點(diǎn)型運(yùn)算,不過(guò)浮點(diǎn)運(yùn)算最為擅長(zhǎng)的應(yīng)該是 GPU。

          也正是因?yàn)?CPU 區(qū)分了類型,上層的匯編、高級(jí)語(yǔ)言才需要區(qū)分變量的類型,CPU 基礎(chǔ)決定了上層建筑。

          四、 編譯型&解釋型

          為什么 C/C++、Java 這類編譯型語(yǔ)言就需要顯示聲明類型,而 Python 這類解釋型語(yǔ)言就不需要呢?

          所以是所有的編譯型都需要申明類型?所有的解釋型都不需要?

          這個(gè)理解是不對(duì)的。

          首先,“編譯”和“解釋”是語(yǔ)言實(shí)現(xiàn)的特征, 語(yǔ)言本身可以以任何一種方式實(shí)現(xiàn)。

          可能我們大多只了解過(guò) C 編譯器(如GCC 、Clang ),卻很少聽(tīng)過(guò) C 解釋器,如 Ch。

          但是,即使使用 Ch 解釋器,我們?nèi)稳恍枰?Ch 解釋的 C 代碼中申明類型。

          為什么 Python 可以不用申明類型?

          因?yàn)?Python 中的對(duì)象模型本身在運(yùn)行時(shí)自帶了“類型”這個(gè)信息,下面是 CPython 源碼中關(guān)于對(duì)象的定義:

          這個(gè)ob_type就是用來(lái) Python 運(yùn)行時(shí)檢測(cè)變量類型的,而 Python 中的所有變量本質(zhì)上都是一個(gè)對(duì)象的“指針”。

          也正因?yàn)槿绱耍琍ython 中的各種變量之間才能隨意賦值,因?yàn)橘x值的本質(zhì)其實(shí)就是改變一下變量所指向的對(duì)象。

          而真正到了解釋執(zhí)行的時(shí)候,Python 解釋器就會(huì)取出這個(gè)類型字段,來(lái)判斷操作是否符合語(yǔ)法,不符合的話就會(huì)運(yùn)行時(shí)報(bào)錯(cuò)。

          這個(gè)_typeobject 結(jié)構(gòu)體的內(nèi)部就定義了對(duì)象一系列的操作,比如 hashfunc、getattrfunc、setattrfunc等。

          那么,為什么 C 即使是解釋執(zhí)行也需要申明類型呢?

          很簡(jiǎn)單,因?yàn)?C 的對(duì)象模型中不會(huì)有”類型“這個(gè)字段,是 int 變量那直接就是 4 個(gè)字節(jié),char 就 一個(gè)字節(jié)。

          而 Python 的 int 變量,除了4 個(gè)字節(jié)的值本身以外,還需要占據(jù)一系列的描述類型的空間。

          也就是說(shuō) C 語(yǔ)言運(yùn)行時(shí)完全沒(méi)有類型這種信息,所以需要在編譯、解釋的時(shí)候就帶上。

          之前偶爾會(huì)聽(tīng)到有人說(shuō) Python 是無(wú)類型的,這是完全錯(cuò)誤的,看過(guò)這篇文章后,相信你一定不會(huì)說(shuō)錯(cuò)了。

          當(dāng)然了,本文也只是簡(jiǎn)單的從粗淺的語(yǔ)法和實(shí)現(xiàn)層面解釋了下,關(guān)于類型系統(tǒng)、類型推導(dǎo)等有人在研究的,這個(gè)也不是咱擅長(zhǎng)的地方,感興趣可以去搜一下。

          Python貓注:關(guān)于 Python 的類型話題,推薦閱讀:《Python到底是強(qiáng)類型語(yǔ)言,還是弱類型語(yǔ)言?》、《辨析編程語(yǔ)言的四種類型:動(dòng)靜類型與強(qiáng)弱類型》

          Python貓技術(shù)交流群開(kāi)放啦!群里既有國(guó)內(nèi)一二線大廠在職員工,也有國(guó)內(nèi)外高校在讀學(xué)生,既有十多年碼齡的編程老鳥(niǎo),也有中小學(xué)剛剛?cè)腴T的新人,學(xué)習(xí)氛圍良好!想入群的同學(xué),請(qǐng)?jiān)诠?hào)內(nèi)回復(fù)『交流群』,獲取貓哥的微信(謝絕廣告黨,非誠(chéng)勿擾!)~


          還不過(guò)癮?試試它們




          Python最佳代碼實(shí)踐:性能、內(nèi)存和可用性!

          Python在計(jì)算內(nèi)存時(shí)應(yīng)該注意的問(wèn)題?

          Python進(jìn)階:如何將字符串常量轉(zhuǎn)為變量?

          有了Python,我能叫出所有貓的名字

          再談文件讀寫:判斷文件的幾種方法及其優(yōu)劣對(duì)比

          Python貓薦書系統(tǒng)之四:《Python源碼剖析》


          如果你覺(jué)得本文有幫助
          請(qǐng)慷慨分享點(diǎn)贊,感謝啦!
          瀏覽 63
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  台湾大香蕉视频网 | 成 人 黄 色 A Ⅴ 网 站 | 色777网站 | 云南省医疗服务质量评估中心官网 | 全部免费毛片在线播放高潮 |