小白詳細的 python 模塊的運用

小白詳細的 python 模塊的運用


什麼是模塊

用書裡的話說:模塊是最高級別的程序組織單元。這句話的意思是,模塊什麼都能封裝,就像這樣:


小白詳細的 python 模塊的運用


在模塊中,我們不但可以直接存放變量,還能存放函數,還能存放類。


小白詳細的 python 模塊的運用


更獨特的是,定義變量需要用賦值語句,封裝函數需要用def語句,封裝類需要用class語句,但封裝模塊不需要任何語句。


之所以不用任何語句,是因為每一份單獨的Python代碼文件(後綴名是.py的文件)就是一個單獨的模塊。


如果你使用過vscode或pycharm等編程工具編寫python程序,每次都需要先創建一個後綴名為.py的Python程序文件,才能運行程序:


小白詳細的 python 模塊的運用


在平時的課堂教學中,其實我們每次運行的代碼,本質上都是在運行一個名為main.py的程序文件:(只不過被隱藏在了終端裡)


小白詳細的 python 模塊的運用


像這樣:每一個單獨的py文件,本質上都是一個模塊。


封裝模塊的目的也是為了把程序代碼和數據存放起來以便再次利用。如果封裝成類和函數,主要還是便於自己調用,但封裝了模塊,我們不僅能自己使用,文件的方式也很容易共享給其他人使用。


所以,我們使用模塊主要有兩種方式,一種是自己建立模塊並使用,另外一種是使用他人共享的模塊。


使用自己的模塊


建立模塊,其實就是在主程序的py文件中,使用import語句導入其他py文件。


小白詳細的 python 模塊的運用


小白詳細的 python 模塊的運用


看,是不是發現main.py文件借用並運行了test.py文件裡的代碼了?這就是import語句起作用了。


模塊相關的常用語句主要有3個,我們接下來一個個來看。


improt語句


小白詳細的 python 模塊的運用


我們使用import語句導入一個模塊,最主要的目的並不是運行模塊中的執行語句,而是為了利用模塊中已經封裝好的變量、函數、類。


小白詳細的 python 模塊的運用


小白詳細的 python 模塊的運用


麻雀雖小,五臟俱全。這段代碼中基本上展現了所有的調用方式。


現在我們要做的是把這段代碼拆分成兩個模塊,把封裝好的變量、函數、類,放到test.py文件中,把執行相關的語句放到main.py文件中。


小白詳細的 python 模塊的運用


你是否注意到,當我們導入模塊後,要使用模塊中的變量、函數、類,需要在使用時加上模塊.的格式。請閱讀主程序main.py的代碼註釋:


小白詳細的 python 模塊的運用


import語句還有一種用法是import…as…。比如我們覺得import story太長,就可以用import story as s語句,意思是為“story”取個別名為“s”。


小白詳細的 python 模塊的運用


另外,當我們需要同時導入多個模塊時,可以用逗號隔開。比如import a,b,c可以同時導入“a.py,b.py,c.py”三個文件。


學完了import語句,我們接著學習from … import …語句。


from...import..語句


from … import …語句可以讓你從模塊中導入一個指定的部分到當前模塊。格式如下:


小白詳細的 python 模塊的運用


小白詳細的 python 模塊的運用


小白詳細的 python 模塊的運用


當我們需要從模塊中同時導入多個指定內容,也可以用逗號隔開,寫成from xx模塊 import a,b,c的形式。我們再運行一個小案例。


小白詳細的 python 模塊的運用


對於from … import …語句要注意的是,沒有被寫在import後面的內容,將不會被導入。


比如以下代碼將會報錯,因為使用了沒有被導入的函數:


小白詳細的 python 模塊的運用


當我們需要從模塊中指定所有內容直接使用時,可以寫成【from xx模塊 import *】的形式,*代表“模塊中所有的變量、函數、類”,我們再運行一個小案例。


小白詳細的 python 模塊的運用


不過,一般情況下,我們不要為了圖方便直接使用【from xx模塊 import *】的形式。


這是因為,模塊.xx的調用形式能通過閱讀代碼一眼看出是在調用模塊中的變量/函數/方法,而去掉模塊.後代碼就不是那麼直觀了。


小白詳細的 python 模塊的運用


小白詳細的 python 模塊的運用


題目要求:在main.py文件導入story模塊,將類Temple的屬性'廟裡有個老和尚,'打印出來。


小白詳細的 python 模塊的運用


要直接使用Temple類的屬性,我們需要在導入的時候指定Temple類(不能直接指定類屬性)。


學會了import語句和from … import …語句後,你就能愉快地導入模塊了。我們接著學習下一個語句。


if __name__ == '__main__'


為了解釋什麼是【if __name__ == '__main__'】,我先給大家講解一個概念“程序的入口”。


對於Python和其他許多編程語言來說,程序都要有一個運行入口。


在Python中,當我們在運行某一個py文件,就能啟動程序 ——— 這個py文件就是程序的運行入口。


小白詳細的 python 模塊的運用


更復雜的情況,我們也可以運行一個主模塊,然後層層導入其他模塊:


小白詳細的 python 模塊的運用


但是,當我們有了一大堆py文件組成一個程序的時候,為了【指明】某個py文件是程序的運行入口,我們可以在該py文件中寫出這樣的代碼:


小白詳細的 python 模塊的運用


這句話的意思是這樣的:


小白詳細的 python 模塊的運用


這裡的【if __name__ == '__main__'】就相當於是 Python 模擬的程序入口。Python 本身並沒有規定這麼寫,這是一種程序員達成共識的編碼習慣。


第一種情況:加上這句話後,程序運行效果不會變化,我們來試試:


小白詳細的 python 模塊的運用

小白詳細的 python 模塊的運用


我們解釋了“當xx.py文件被直接運行時,代碼塊②將被運行”,再解釋一下“xx.py文件作為模塊是被其他程序導入時,代碼塊②不被運行。”


我們來運行體驗兩段代碼。這是第一段:


小白詳細的 python 模塊的運用

小白詳細的 python 模塊的運用


第一段代碼沒有使用if __name__ == '__main__',所有語句都會被運行。


第一段代碼沒有使用if __name__ == '__main__',所有語句都會被運行。


小白詳細的 python 模塊的運用

小白詳細的 python 模塊的運用


現在我們運行代碼的時候,會發現if __name__ == '__main__'下的語句不會被執行。這是因為B.py文件並不是我們現在的程序運行入口,它是被A.py文件導入的。


關於這一個點目前你只需有個印象即可。接下來,我們來看看如何“使用他人的模塊”。


初探借用模塊


time模塊和random模塊是Python的系統內置模塊,也就是說Python安裝後就準備好了這些模塊供你使用。


此外,Python作為一門膠水語言,一個強大的優勢就是它擁有許多第三方的模塊可以直接拿來使用。


如果是第三方編寫的模塊,我們需要先從Python的資源管理庫下載安裝相關的模塊文件。


下載安裝的方式是打開終端,Windows用戶輸入pip install + 模塊名;蘋果電腦輸入:pip3 install + 模塊名,點擊enter即可。(需要預裝python解釋器和pip)


比如說,爬蟲時我們會需要用到requests這個庫(庫是具有相關功能模塊的集合),就需要在終端輸入pip3 install requests(Mac用戶)的指令。


小白詳細的 python 模塊的運用


第三方模塊的使用我們會在之後的其他課程具體介紹,今天我們主要來學習Python的內置模塊。


如果內置模塊是用Python語言編寫的話,就能找到py文件:


小白詳細的 python 模塊的運用


我們用命令random.file找出了random模塊的文件路徑,就可以去打開查看它的代碼:


小白詳細的 python 模塊的運用


我們熟悉的函數random.choice(list),功能是從列表中隨機抽取一個元素並返回。它的代碼被找到了:


小白詳細的 python 模塊的運用


另一個熟悉的函數random.randint(a,b),功能是在a到b的範圍隨機抽取一個整數。它的代碼也被找到了:


小白詳細的 python 模塊的運用


像這樣,通過閱讀源代碼我們能找到所有能夠使用的變量、函數、類方法。


雖然你可以通過看源代碼的方式來理解這個模塊的功能。但如果你想要高效地學會使用一個模塊,看源代碼並不是最佳選項。我們接著談談“如何自學模塊”。


如何自學模塊


學習模塊的核心是搞清楚模塊的功能,也就是模塊中的函數和類方法有什麼作用,以及具體使用案例長什麼樣。


用自學“random”模塊為例,如果英文好的同學,可以直接閱讀官方文檔:https://docs.python.org/3.6/library/random.html


搜到教程後,我們重點關注的是模塊中的函數和類方法有什麼作用,然後把使用案例做成筆記(還記得第8關談到的如何做學習筆記麼?)。


例如random模塊的關鍵知識(也就是比較有用的函數和類方法),可以做成這樣的筆記:


小白詳細的 python 模塊的運用


另外,我們還可以使用dir()函數查看一個模塊,看看它裡面有什麼變量、函數、類、類方法。


小白詳細的 python 模塊的運用


這就像是查戶口一樣,可以把模塊中的函數(函數和類方法)一覽無餘地暴露出來。對於查到的結果“xx”結構的,它們是系統相關的函數,我們不用理會,直接看全英文的函數名即可。


這樣查詢的好處是便於我們繼續搜索完成自學。比如我們在列表中看到一個單詞“seed”,我們就可以搜一搜random.seed的用法:


甚至不是模塊,我們也可以用這種方式自學:dir(x),可以查詢到x相關的函數,x可以是模塊,也可以是任意一種對象。


小白詳細的 python 模塊的運用


好,我們回到模塊上。再次總結一下模塊的學習方法,其實可以歸納成三個問題:


小白詳細的 python 模塊的運用


這裡想提醒大家的是,比較小的模塊(比如random模塊)可以通過這樣的方式自學,大型模塊的學習就比較困難(除非你有充足的專業背景知識)。


例如數據分析需要用到pandas和NumPy模塊,網頁開發要用到Django模塊等等,這些大型模塊最好還是在課程上系統學習,避免散亂的學習形不成知識體系。


以目前大家的水平來說,有一些很實用,又不難學的模塊,已經足夠我們探索了。在今天的最後,我想手把手帶大家自學一個模塊。


學習CSV模塊


今天想帶大家學習的模塊是csv模塊。之所以教大家這個模塊,是因為這個模塊既簡單又實用。


csv是一種文件格式,你可以把它理解成“簡易版excel”。學會了csv模塊,你就可以用程序處理簡單的電子表格了。


小白詳細的 python 模塊的運用


如果要手動新建csv文件,我們可以先新建一個excel表格,然後選擇另存為“csv”格式即可。


小白詳細的 python 模塊的運用


同樣的,當我們有了一張csv格式的表格,我們也可以選擇另存為“excel”格式。


對csv文件的介紹就到這裡。下面繼續學習如何用csv模塊讀寫csv文件。

我們使用import語句導入csv模塊,然後用dir()函數看看它裡面有什麼東西:


小白詳細的 python 模塊的運用


同時,我們可以搜索到csv模塊的官方英文教程:

https://docs.python.org/3.6/library/csv.html


中文教程:https://yiyibooks.cn/xx/python_352/library/csv.html#module-csv


如果你要通過閱讀這份教程來學習csv模塊的話,最簡單的方式是先看案例(拉到教程的最後),遇到看不懂的函數,再倒回來查具體使用細節。


如果你要通過閱讀這份教程來學習csv模塊的話,最簡單的方式是先看案例(拉到教程的最後),遇到看不懂的函數,再倒回來查具體使用細節。


小白詳細的 python 模塊的運用

現在我們也跟著案例動手試試如何讀取csv文件,可見open()後面跟了兩個參數,用csv.reader(文件變量)創建一個reader對象。


我們新建了一個名為test.csv的文件,裡面的內容是這樣:


小白詳細的 python 模塊的運用


然後我們運行learn_cse.py文件的幾行代碼,你就能print出csv文件中的每一行信息。


小白詳細的 python 模塊的運用


我們可以看到,終端輸出的每一行信息都是一個列表。

我們來做一個練習,下面有一個csv文件:


小白詳細的 python 模塊的運用


你來試試把它的每一行打印出來吧:


小白詳細的 python 模塊的運用


以上就是讀取csv文件的寫法,接下來我們來看如何往csv格式文件寫入數據。


寫入數據的方式是這樣的:


小白詳細的 python 模塊的運用


先創建一個變量名為writer(也可以是其他名字)的實例,創建方式是writer = csv.writer(x),然後使用writer.writerow(列表)就可以給csv文件寫入一行列表中的內容。


另外關於open函數的參數,也就是圖中的'a',我們來複習一下:


小白詳細的 python 模塊的運用


我們來做一個練習,還是這個商品列表的csv文件:


小白詳細的 python 模塊的運用


你來試試用writerow()方法為它追加寫入兩行列表吧:['4', '貓砂', '25', '1022', '886']、['5', '貓罐頭', '18', '2234', '3121']。


小白詳細的 python 模塊的運用


到這裡,最基本的csv表格讀取和錄入方法我們就已經學會了。csv模塊雖然比random模塊稍微複雜一點點,但按照模塊三問(這模塊有哪些函數可用?有哪些屬性或方法可用?使用格式是什麼?)的學習方式,我們一樣可以學會它的基本用法。


小白詳細的 python 模塊的運用

小白詳細的 python 模塊的運用


至於編程的魔法世界,你已經能看明白這個世界的構造,懂得學習的方法和進階的路徑,我們稱之為初窺門徑。


這是我們當下的仰望星空,但並非終點。如果你肯把頭抬得更高,你還能看到另一片更廣闊的天地,是開源精神培育的熱土。


Python的模塊正是開源精神的一塊塊切片。在網絡上也有很多優秀的開發者在分享著自己的代碼。他們不計辛勞,不計報酬的付出,只是單純地為了思想的碰撞,為了幫助其他人提高效率,共同推動互聯網進步發展。


--------------------------------------------------------

練習一

一個沒用模塊的“時間記錄器”

請運行左側的代碼,並讀懂代碼中的每一行。

涉及知識:判斷、循環、文件讀寫等。

注:新建文件,在“步驟”旁的“文件”裡查看。

# 不用 time模塊 的時間記錄器。

input("歡迎使用“時間管理器”!請按回車繼續。")

while True:

task_name = input('請輸入任務名:')

task_time = int(input('你覺得自己至少可以專注這個任務多少分鐘?輸入 N 分鐘'))

input('此次任務信息:\\n我要完成的任務:%s\\n我至少要專注:%d分鐘\\n按回車開始專注:'%(task_name,task_time))

task_status = input('請在任務完成後按輸入y:')

actual_time = input('該任務實際用時為幾分鐘?')

if task_status == 'y':

with open('timelog1.txt','a', encoding = 'utf-8') as f: # 將時間日誌文檔和代碼放一起。

f.write(task_name + ' 的預計時長為:' + str(task_time) + '分鐘\\n')

f.write(task_name + ' 的實際時長為:' + str(actual_time) + '分鐘\\n')

again = input('建立一個新任務請按 y, 退出時間日誌記錄器請按 q:')

if again == 'q':

break

else:

print('抱歉,你的輸入有誤。請重啟時間記錄器。')

print('願被你善待的時光,予你美好的回贈。')

----------------------------------------------------------------------------------------


只要我們想通過編程做到更多的事,就避不開主動了解更多知識。

所以,這次的練習,想將主動權更多地交在大家手裡。


請你通過搜索和自學,瞭解並運用下面兩個新知識:


time模塊中的時間戳(可進行日期運算)和格式化日期(可將日期轉換成平常我們所見的格式);


倒計時的功能怎麼用print()函數實現,屬於之前沒有講過的方法,需要去搜索新的知識。


# 第一行:必不可少的調用模塊。

import time

input("歡迎使用“時間管理器”!請按回車繼續。")

while True:

count = 0

task_name = input('請輸入任務名:')

task_time = int(input('你覺得自己至少可以專注這個任務多少分鐘?輸入 N 分鐘'))

input('此次任務信息:\\n我要完成的任務:%s\\n我至少要專注:%d分鐘\\n按回車開始專注:'%(task_name,task_time))

# 下面應該要有兩行代碼,自動記錄可以計算以及可以打印的開始時間。


#a = int(input('time:'))

b = task_time * 60

# 這裡可以加一個倒計時,實時顯示還剩多少時間,可參考左側提供的資料。代碼量大概有5行。

while (count < b):

ncount = b - count

print('倒計時開始:%d秒'%(ncount))

time.sleep(1)

count += 1

print('時間到!')

task_status = input('請在任務完成後按輸入y:')

actual_time = input('該任務實際用時為幾分鐘?')

if task_status == 'y':

# 下面應該要有兩行代碼,自動記錄可以計算以及可以打印的結束時間。

# 有了自動記錄的始末時間後,記錄的代碼也需要隨之改變。

with open('timelog2.txt','a', encoding = 'utf-8') as f:

f.write(task_name + ' 的預計時長為:' + str(task_time) + '分鐘\\n')

f.write(task_name + ' 的實際時長為:' + str(actual_time) + '分鐘\\n')

again = input('建立一個新任務請按 y, 退出時間日誌記錄器請按 q:')

if again == 'q':

break

else:

print('抱歉,你的輸入有誤。請重啟時間記錄器。')

print('願被你善待的時光,予你美好的回贈。')

--------------------------------------------------------------------------------------------

input("歡迎使用“時間管理器”!請按回車繼續。")

while True:

task_name = input('請輸入任務名:')

task_time = int(input('你覺得自己至少可以專注這個任務多少分鐘?輸入 N 分鐘'))

input('此次任務信息:\\n我要完成的任務:%s\\n我至少要專注:%d分鐘\\n按回車開始計時:'%(task_name,task_time))

start = time.time() # 開始計時

start_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())) # 格式化日期


# 實際代碼:分鐘轉成秒要乘60,用-1來倒計時。

# for t in range(task_time*60,0,-1):

for t in range(task_time,0,-1):

info = '請專注任務,還要保持專注 ' + str(t) + ' 秒哦!'

print(info,end="")

#print() 函數會把內容放到內存中, 內存中的內容並不一定能夠及時刷新顯示到屏幕

# 中(應該是要滿足某個條件,這個條件現在還不清楚)。 使用flush=True之後,會在

# print結束之後,不管你有沒有達到條件,立即將內存中的東西顯示到屏幕上,清空緩存。

# 使用場景:

#1.尤其是在while循環中,要想每進行一次while循環體,在屏幕上更新打印的內容就得使用flush = True的參數。

#2. 打開一個文件, 向其寫入字符串, 在關閉文件f.close()之前, 打開文件是看不到寫入的字符的。 要想在關

# 閉之前實時的看到寫入的字符串,應該用flush = True.

print("\\b"*(len(info)*2),end="",flush=True)


time.sleep(1)

print('你已經專注了 %d 分鐘,很棒~再加把勁,完成任務!'%task_time) # 倒計時後,才繼續運行之後的代碼。

# 詢問任務是否完成

task_status = input('請在任務完成後按輸入y:')

if task_status == 'y':

end = time.time() # 一定用戶按了 y,就記下結束時間。

end_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())) # 日期格式化

actual_time = int((end -start)/60) # 始末時間相減,從秒換算到分,除以60。

start_end = start_time + '——' + end_time + '\\n'


with open('timelog3.txt','a', encoding = 'utf-8') as f:

f.write(task_name + ' 的預計時長為:' + str(task_time) + '分鐘\\n')

f.write(task_name + ' 的實際時長為:' + str(actual_time) + '分鐘,具體時間為:' + start_end)

again = input('建立一個新任務請按 y, 退出時間日誌記錄器請按 q:')

if again == 'q':

break

else:

print('抱歉,你的輸入有誤。請重啟時間記錄器。')

print('願被你善待的時光,予你美好的回贈。')

----------------------------------------------------------------------------

練習二

os模塊學習

#同樣,運行後重新打開文件查看變化

import os

with open ('test.txt','r') as f:

lines = f.readlines()

with open('test_new.txt','w') as new: # 新建一個文檔

for line in lines:

if line not in ['0\\n','1\\n']:

new.write(line)

# 可以先運行一次代碼,然後,再將下面代碼的註釋取消,再運行一次。

os.replace('test_new.txt', 'test.txt') # 語法:os.replace(file1,file2),將file1重命名為file2,將其替代。

# 請你根據上面的方法,將之前的代碼改為用模塊 os 實現(可選文檔poem2)。

# 在改代碼之前,可以先將上面的代碼註釋,然後取消下面代碼的註釋。

list_test = ['一弦一柱思華年。\\n','只是當時已惘然。\\n']

with open ('poem2.txt','r',encoding='utf-8') as f:

lines = f.readlines()

with open('new_poem.txt','w',encoding='utf-8') as new:

for line in lines:

if line in list_test:

new.write('____________。\\n')


else:

new.write(line)

os.replace('new_poem.txt','poem2.txt')

'''

os.getcwd() # 返回當前工作目錄

os.listdir(path) # 返回path指定的文件夾包含的文件或文件夾的名字的列表

os.mkdir(path) # 創建文件夾

os.path.abspath(path) # 返回絕對路徑

os.path.basename(path) # 返回文件名

os.path.isfile(path) # 判斷路徑是否為文件

os.path.isdir(path) # 判斷路徑是否為目錄


分享到:


相關文章: