發現許多小夥伴入門Python幾個月,還是低效率做數據處理。這套課程以形象的示意圖,精心安排的案例,循序漸進帶你玩轉數據處理分析神器——pandas,課程中還有分析案例噢,乾貨滿滿!
經過前2節的學習,我們已經可以把常用的功能包裝到函數中,但是這些函數只能在一個項目中重複使用。如何管理能在不同項目中通用的函數?這需要學習關於模塊的概念
模塊?啥玩意
我們從一個實際需求出發,再對應上那些難懂的概念術語。
如果你的工作數據源來自於文件(excel,csv等),那麼經常會遇到文本轉數值的任務:
文本轉數值很簡單,難的是轉換失敗的情況:
根本看不出來具體哪一列出現問題
於是,你寫了一個通用函數處理這種情況,現在調用代碼非常簡單:
直接看看文件:
這就很方便看出來哪些列出問題
現在的問題是,這種任務在不同的項目也需要用上。怎麼辦?這不能每次都複製代碼到新項目上吧。
於是,我們需要把這些通用函數寫到一個單獨的文件上:
這個文件就是稱為"模塊",文件名就是模塊名
這裏簡單地把"模塊"理解為,把多個函數組織在一起的工具
當需要使用模塊中的函數時,只需要執行"導入":
行1(上):導入模塊。
行3:通過 模塊變量.函數() 就能執行函數
劃重點:
之前章節講解過定義函數,實際是生成函數對象,賦值(對象id)給與函數同名的變量上。模塊同樣是對象
import myHelper ,實際是加載(執行)模塊文件,得到了模塊對象,然後把對象賦值給 myHelper這個變量上
import myHelper as mh,過程基本同上,只是變量是 mh 而已
也可以直接把函數導入:
行1:當需要把模塊中的東西(變量)導入,則需要使用 from 模塊名 import 模塊中的變量
劃重點:
建議使用方式1,導入模塊,通過模塊+函數名字訪問。可以讓代碼更加清晰,也能防止不同模塊函數名字相同產生的問題
但是,這沒有解決問題。難道另一個項目需要用這個模塊,我就把文件複製過去?
Python 如何尋找模塊?
既然不能把代碼文件(模塊)複製放入多個項目,那麼就把代碼文件放入電腦中一個公共的文件夾中,其他的項目執行 import 語句時,就到那裏去找。這就解決了問題。
於是,Python 有一套規則,看一下代碼:
導入時,Python 會按照上圖列表中的路徑,依次查找,直到找到為止。都找不到就會報錯
列表中第一個路徑通常是執行代碼文件所在目錄。這就是為什麼把模塊文件放在項目文件夾中就可以導入的原因
你會注意到有一個路徑,lib\site-packages ,這就是平時通過 pip 安裝的包所在目錄。這就是為什麼我們 import pandas 能夠成功的原因
劃重點:
查找包是按 sys.path 列表順序查找,因此要會出現搶先導入的情況。比如在項目文件夾中創建一個 pandas.py 模塊,此時如果導入 pandas ,只會導入我們自定義的 pandas 模塊
你會注意到列表中第二個路徑是一個 zip(壓縮文件),這意味着可以把多個模塊文件壓縮。Python 會自動解壓後加載
lib\site-packages 的具體路徑,在於設置的環境變量 Path
現在,我們其實已經知道幾種解決問題的方式。
最簡單直觀但略顯笨拙的方式,就是把我們的模塊文件直接放入 lib\site-packages 文件夾中。這種方式我就不演示了。
有時候我們希望在電腦某個自定義的文件夾中放入我們的自定義模塊,畢竟在 lib\site-packages 文件夾中存放很多其他的包。
因為 sys.path 是一個列表,我們可以執行一句代碼,往列表插入新的路徑:
一定要在導入操作之前執行"添加新路徑"的操作
本例中新路徑在列表最後,需要注意被前面的路徑搶先導入的情況
這可以解決問題,但每個新項目都要執行這段代碼,很不方便。
這就需要最後一種方式
Python 啓動時,會生成 sys.path ,其中,如果發現在 lib\site-packages 文件夾中有後綴 .pth 的文件時,會讀取其中的內容。
如下是我電腦下 lib\site-packages\pywin32.pth 文件內容:
每一行是一個路徑,這些路徑都會被放入 sys.path 中
我們只需要把自定義的文件夾路徑寫入這個文件的新行,就能讓所有項目找到我們自定義的模塊
劃重點:
你可以在 lib\site-packages 文件夾中新建任意名字的 pth 文件,同樣有效
.pth 文件中還可以執行代碼
現在來一次演練
假設我定義了一系列的函數,放入模塊文件 myHelper.py 文件,放入電腦中某個目錄下:
現在希望這個文件夾路徑能放入 sys.path 中,於是我在 lib\site-packages 文件夾中創建一個名為 mypath.pth 的文件,其中寫上目標文件夾路徑:
一切大功告成。現在試試隨意打開一個項目,導入自定義模塊:
由於之前我們在項目文件夾下創建了 myHelper.py ,此時記得把他刪除掉。因為 mypth.pth 中的路徑只會添加在 lib\site-packages 之後
還需要重啓你的 jupyter notebook 。這是因為同一個名字的模塊,一個進程只會生成一次。之前生成的時候已經標記為當前項目所在文件夾,不重啓再次導入,會出現找不到模塊的錯誤
咦?為什麼會輸出了一句話?
這是因為我在模塊文件中執行了一些代碼。
接下來,我們講稍微深入瞭解,導入模塊時到底發生了什麼
變量空間
這個機制是一個比較關鍵的地方。
在編寫代碼時,變量是一個必不可少的工具。
比如:pd.read_excel() 能加載數據為 DataFrame ,如果不用變量"持有"這個 DataFrame 對象,充其量你只能顯示一下數據,後續就沒法進一步操作。
通過前兩節的內容我們也知道了,其實定義函數也是定義了變量從而"持有"了函數對象。
不僅是定義函數,就連定義類,也是在創建變量與對象
一個模塊被導入,模塊中的代碼就會被執行。執行過程中創建的變量都會被保存在模塊變量空間中
import myHelper ,由於導入時沒有指定空間名,默認與模塊名一致
此時模塊文件中的代碼被執行,其中定義的任何變量都被保存在模塊空間中。
模塊空間通過變量 myHelper 訪問
這就是為什麼訪問模塊中函數時需要通過 模塊名.變量名 訪問。如: myHelper.func() 即調用其中的函數。實際是 模塊空間變量.變量名
import myHelper as mh ,如果嫌棄模塊名字太長,可以在導入時指定空間變量名
一次 Python 進程中,對同一個模塊的導入始終只執行一次。意味着你寫多行的 import myHelper 實際只有第一次導入會執行模塊中的代碼
這就是為啥你用 jupyter notebook 等交互方式執行代碼,會發現修改模塊代碼後不管怎麼執行都不能看到修改後效果。
此時需要重啓當前頁面的 Python 進程