對於新手來說,Python中有哪些難以理解的概念?

2021-09-26 04:28:35 字數 2867 閱讀 6460

老手都是從新手一路走過來的,很多新手夥伴可能會對一些基礎的概念理解都存在一定的困難,提起python中難以理解的概念,很多夥伴對於python變數賦值的機制有些疑惑,不過對於習慣於求根究底的程式設計師,只有深入理解了某個事物本質,掌握了它的客觀規律,才能得心應手、運用自如,高階更高層次來看待這個事物,此刻「庖丁解牛」這個成語能夠貼切表達這個意思,你看見的是整頭的牛,而我看見的是牛的內部肌理筋骨,就是這個狀態!!!

那麼為什麼python變數賦值的機制難以理解呢?

我想可能是我們的思維被c語言變數賦值的機制所固化了。在c語言中變數所分配到的位址是記憶體空間中乙個固定的位置,當我們改變變數值時,對應記憶體空間中的值也相應改變。在python中變數儲存的機制是完全不一樣的,當給乙個變數賦值時首先直譯器會給這個值分配記憶體空間,然後將變數指向這個值的位址,那麼當我們改變變數值的時候直譯器又會給新的值分配另乙個記憶體空間,再將變數指向這個新值的位址,所以和c語言相比,在python中改變的是變數所指向的位址,而記憶體空間中的值是固定不變的。

接下來我們要由淺入深的去驗證下我們的結論。在ubuntu 16.04 lts 32 位的環境下通過id方法檢視變數的記憶體位址的方式來進行驗證,為什麼要強調環境呢?因為不同的環境下測試結果可能會由於直譯器的優化不同而有所不同。

那這裡我們就以python的int型別為例,可以看到執行 i += 1 後,變數i的記憶體位址會發生變化,事實上 i += 1 並不是在原有變數i的位址上加1,而是重新建立乙個值為6的int物件,變數i則引用了這個新的物件,因此當變數i和變數j的值相同時會指向同個記憶體位址。同樣以python的float 型別為例也驗證了這個變數儲存管理的機制。

———————— int example————————

i = 5 ——》 i —> 5 id(i) —> 0xa26f880

i += 1 ——》 i —> 6 id(i) —> 0xa26f874

j = 5 ——》 j —> 5 id(j) —> 0xa26f880

________________ float example_______________

i = 1.5 ——》 i —> 1.5 id(i) —> 0x9e86c8c

i += 1 ——》 i —> 2.5 id(i) —> 0x9e86cac

j = 1.5 ——》 j —> 1.5 id(j) —> 0x9e86c8c

陸陸續續的試了列表、字典、字串、元組等變數型別賦值的效果,我發現其實python中的物件分為可變型別和不可變型別,列表、字典是可變型別,而整數、浮點、短字串、元組等是不可變型別。可變型別的變數賦值與我們了解的c語言機制相同,而不可變型別的變數賦值時,實際上是重新建立乙個不可變型別的物件,並將原來的變數重新指向新建立的物件,當然如果沒有其他變數引用原有物件時,原有物件就會被**。這也是python作為動態型別語言的特點,即變數不需要預先宣告型別,當變數在賦值時直譯器會根據值的型別建立對應的記憶體空間進行儲存,並將變數指向這個位址空間即可,比如執行a=1時,直譯器將變數指向整形值1的位址,當執行a=0.1時,直譯器將變數指向浮點值0.1的位址。

但是問題又來了!!!為什麼python可以這樣肆無忌憚地完成動態型別的特徵?

這裡要深究到pyobject這個結構體的層面。通常來說,無論什麼語言最終被計算機識別到的都是記憶體中的位元組資訊,物件實際上就是在更高的層次上把記憶體上的資料作為乙個整體來考慮,比如乙個整數或是乙個字串。python中所有的東西都是物件,它們擁有一些相同的內容,這些內容定義在pyobject這個結構體中。

typedef struct _object  pyobject;
ob_refcnt是乙個整形變數,它的作用是實現引用計數機制。比如乙個物件a,當有乙個新的pyobject *引用該物件時,a的引用計數增加;而當這個pyobject *被刪除時,a的引用計數減少。當a的引用計數減少到0時,a就可以從堆上被刪除,以釋放出記憶體供別的物件使用。ob_type是乙個指向_typeobject結構體的指標,這個結構體實際上也是乙個物件,它是用來指定乙個物件型別的型別物件,這個型別物件記錄了不同的物件所需的記憶體空間的大小資訊。那麼簡單的說,python中物件機制的核心乙個是引用計數,乙個就是型別。

pyobject是乙個定長物件的結構體,對於可變長度物件的結構體是pyvarobject,它比pyobject結構體多乙個ob_size變數,用於指定容器中包含的元素數量。比如list中有5個元素,那麼pyvarobject.ob_size的值就是5。pyvarobject實際上只是對pyobject的乙個擴充套件而已,任何乙個pyvarobject所占用的記憶體,開始部分的位元組定義和pyobject是一樣的。這就可以解釋說,當python建立乙個整形物件pyintobject,首先它會為這個物件分配記憶體,並進行初始化,然後這個物件會由乙個pyobject變數來維護,因為每乙個物件都擁有相同的物件頭部,這使得物件的引用變得非常的統一。無論物件實際上的型別是什麼,只需要通過pyobject指標就可以引用任意的乙個物件。

深入淺出了python變數賦值的機制以後,大家就不覺得這是難以理解的概念了吧!

其實學習的樂趣就體現在恍然大悟、融會貫通的那一時刻。

原創對於新手來說有點「蛋疼」

估計好多新人在學習seo以前,聽到的大多數人講的 seo很好做的,只要會開電腦就行。結果呢?好多人在剛學的時候,總是想在網上多學點有關seo的知識,但是花了幾天時間,認真看了幾個老師的教程,傻眼了 好多人把 zac老師的 seo實戰教學 講成神書,但是在一些新人看來,這些無非是天書。或者說,他在用他...

從事seo的老站長相對於新手來說優勢在哪?

seo它是一項技術,雖然入門容易,但是vpzilec真正要掌握它的內涵,不是每個站長都能夠輕而易舉的掌握的 對於那些對seo不屑一顧的站長來說,或許您老人家是剛接觸,沒有掌握其中的奧妙所在,把簡單幾個冷門關鍵詞做上去,就學會了seo嗎?其實是想得太天真了,seo其實是需要長期的實戰才能知道其中的真理...

對於非程式猿來說,我們能用python來做些什麼?

對於學習python的動機,對於專業的程式猿來說,當然是一門手藝。優秀的程式猿年薪百萬,能夠實現財務自由過上理想的生活。但是程式猿也不是所有人都能當的,第一是需要年富力強的腦力和體力 第二是需要經過大量的程式設計的訓練 第三可能還需要一點點的天賦。更何況程式猿工作辛苦,還會有禿頭的風險。所以不是所有...