申明: 本站飛宇網 https://feiyetopro.blogspot.com/。自網路收集整理之書籍、文章、影音僅供預覽交流學習研究,其[書籍、文章、影音]情節內容, 評論屬其個人行為, 與本網站無關。版權歸原作者和出版社所有,請在下載 24 小時內刪除,不得用作商業用途;如果您喜歡其作品,請支持訂閱購買[正版]。謝謝!
[課後作業] 第051講:__name__屬性、搜索路徑和包|課後測試題及答案
《零基礎入門學習Python》視頻下載地址:傳送門
-GN=6Ys_5HZ^<:M2!OK|$k9f+0
測試題(筆試,不能上機哦~):
;b5Q3c9P:TDNdHX)Mi B^v=V
0. __name__屬性的含義是什麼?%4-!X7n
SN<GV3L(tJqvwIe|r&g^K8
o;7,EO9N(?i#.t]wmH%xLlfpJ=aknM
1.什麼時候__name__屬性的值是"__main__"?T*eFN? K |
1 6Oul,?M*etgYpowf]jvIc}m0(
xW_Quk0T&bHL@n`FG1fI ?(s
2.如果獲得當前Python的搜索路徑?;fZK^Y"s
jw%8~tfv&OT$k,^mJh"( nd
Z;l1[jT:+a*5}PR'^|"u63@O
3.如果你不想將相關的模塊文件放在當前文件夾內,那最好的選擇是?{]y8r
q,% tMTzIUG "1R{HY>Jv~P
vW86yU(A?9Vrb.Bhw|%>_'L]d@#Cj
4.如果你見到import urllib. request語句,那麼這個urllib是什麼?4b|x@Q
[~2KtA*.OqSve)y4x#!g1T('Ca
I+=yt:fw6h@"4[1^)POXU|`WEK!
5. Python如何區分一個文件夾是普通文件夾還是包?TdK5;(
2 ~[AIw,cmt!Qb:gr=03Fsn+x
EU,rGF^3t!O%7=8v4p kd6z&e
動動手(一定要自己動手試試哦~):nlbS.>-*K
sw7TB.SlC~a' xjo"@q?2
0.執行下邊a.py或b.py任何一個文件,都會報錯,請改正程序。
H+~<&T%.{VR'b_]A;4hpxUL8!vX [t*
注:這道題原理跟上一節課的課後作業(測試題4、5)類似,如果上節課你搞懂了,這道題應該可以想出解決方案,不要輕易看答案,除非你已經抓破頭皮…… .&|]~KPY3S
o[)T{EqBv&ta^%Kdj8l$+;>C
- # a.py
- import b
- def x():
- print('x')
- by()
- # b.py
- import a
- def y():
- print('y')
- ax()
- 執行b.py 引發下邊異常:
- >>>
- Traceback (most recent call last):
- File "/Users/FishC/Desktop/b.py", line 1, in <module>
- import a
- File "/Users/FishC/Desktop/a.py", line 1, in <module>
- import b
- File "/Users/FishC/Desktop/b.py", line 6, in <module>
- ax()
- AttributeError: 'module' object has no attribute 'x'
複製代碼
2ebN?1-Yqif:cETG8_`pAD7'F9P
1.下邊是一個Python項目的基本結構,請你合理組織它們,便於維護和使用。
2ebN?1-Yqif:cETG8_`pAD7'F9P
魚C大項目.zip (3.87 KB,下載次數: 969) 9#UA|Xk
c4r%w<mi{B^v=)fk]5z`$
N1qFvo&HcOLd>pi}<-x9!uGsT*SU#$
^[%w{yFL)Oidmk9~-S34W;n
2.請寫下這一節課你學習到的內容:格式不限,回憶並複述是加強記憶的好方式!
貪一時之快先看答案,您將失去一次鍛煉的機會!=@"(&
oS-H13QA[ONZY ^W6=+)B
請先自己動手,再回複查看參考答案! &y5dZ)
LWjR+#.tUi`8T^g}Ib4|=OCd1
測試題答案:
本帖隱藏的內容
0. __name__屬性的含義是什麼?zU[osqNM
|`}i_d=n+V.Ex,)>05N!*RJ&^LF
答:所有模塊都有一個__name__屬性,__name__的值取決於如何應用模塊,在作為獨立程序運行的時候, __name__屬性的值是'__main__',而作為模塊導入的時候,這個值就是該模塊的名字了。Z+teSR@Yn
~bmp "$M]Iza0Fc2B6ekhKuW
c7@hke~VQ:Z n!%v5i?yI-soF=
1.什麼時候__name__屬性的值是"__main__"?OxE2Q
!<6)#+4m *&kVU?WM,d>L
答:請參考上一題答案。Powered by bbs.fishc.com
!}9omgYS=Gk[v*K%&VilFT7:Oa
'x!:X)C8b_A@stp46&]2uB*; LqV
2.如果獲得當前Python的搜索路徑?O+cTiGI1A
a1X+UZ^>y)ovK'sW28,L*f
答:我們可以通過sys模塊中的path變量顯示出來(不同的機器上顯示的路徑信息可能不一樣)。IU&k"N|[M
- >>> import sys
- >>> sys.path
- ['', 'C:\\Python34\\Lib\\idlelib', 'C:\\WINDOWS\\SYSTEM32\\python34.zip', 'C:\\Python34\\DLLs', 'C:\\ Python34\\lib', 'C:\\Python34', 'C:\\Python34\\lib\\site-packages']
複製代碼
3. 如果你不想將相關的模組檔放在當前資料夾內,那最好的選擇是?
@-[%_T~s!wH.=k1)8V<G'5,9(>60
答:放在 site-packages 資料夾,因為它就是用來存放你的模組檔的。E&qw:"
4Vw*tE^(N8,X;CHGmQp2A>&BM9
Gd]<SZ>)=M~wOEVm^pq#
4. 如果你見到 import urllib.request 語句,那麼這個 urllib 是什麼?
0O#hN^|>`Sgbskp}ad3KF?
答:是一個包,Python 把同類的模組放在一個資料夾中統一管理,這個資料夾稱之為一個包。
urllib 是 Python 負責管理 URL 的包,用於訪問網址(後邊我們會講到)。a<e4(w"AG
V[`Ec7Aq8yU!='2"}-M9e$
6U<'>[PA;W-x7#9JKfV^w+q2!my
5. Python 如何區分一個資料夾是普通資料夾還是包?BOiETj0(+h
N62s$YnuWJf}eT,?AM*8_wDh@
答:看資料夾中是否有 __init__.py 文件。tm$S-2H^*r
1};|xs*hWEA()#u'bDp&^
必須在包資料夾中創建一個 __init__.py 的模組檔,內容可以為空。可以是一個空檔,也可以寫一些初始化代碼。這個是 Python 的規定,用來告訴 Python 將該目錄當成一個包來處理。2~!,D}
版權屬於:bbs.fishc.com
Y_+Ot]x,)6q?BmK"PM5G[R
動動手答案:來自:bbs.fishc.com
本帖隱藏的內容
版權屬於:bbs.fishc.com
0.執行下邊a.py或b.py任何一個文件,都會報錯,請改正程序。-T';|Q
a->WV85&AI{o0FpM3 vxk4
答:因為在執行b.py的加載過程中,需要創建新的模塊對象b,然後執行b.py對應的字節碼。當遇到第一條語句(import a)的時候,Python會轉而去導入a.py並生成模塊對象a。同樣遇到第一條語句(import b)的時候,Python就跑去導入模塊b,此時發現b模塊已經導入(在sys.modules中存在),繼而執行b模塊的字節碼,當執行到ax()的時候,由於模塊a此時並未完全導入,所以拋出AttributeError異常。)}`,ewF
~lPQM=JZk.0tf:$5N9uC*H7AG"Wb
怕有些魚油可能看不懂,小甲魚給大家整理下,看Python是如何被當成猴子耍的:?rY&)ITWA
執行b. py -> import a ->查找a模塊->未發現a模塊對象->導入a.py -> import b ->查找b模塊->發現b模塊對象->接著往下執行字節碼(import a已執行過,Python有機制確保不重複導入,因而不會再執行) -> ax() ->在a模塊中找不到x(),因為a還沒有被完全導入嘛…… jY'$tgql
Sfw8mBohE;tG4J,ZO*1'DQi@
好了,解決的方案也很簡單,用這節課的知識,就是使用if __name__ == "__main__"來確保Python不要在導入的過程中調用不該調用的函數。>IYhgkL2Cc
{Iz01KTx8t|95g.R'*7Hmu
所以應該這麼寫:來自:bbs.fishc.com
- # a.py
- import b
- def x():
- print('x')
- if __name__ == "__main__":
- by()
- # b.py
- import a
- def y():
- print('y')
- if __name__ == "__main__":
- ax()
複製代碼
:)h=3}v|]<`#X&GMN'qweEiUJ^QOx
1.下邊是一個Python項目的基本結構,請你合理組織它們,便於維護和使用。Ad:56
k 5K'D+*jP7wWZxQA<TBlqS
答:通過將相關的模塊組織成包,使項目結構更為完善和合理。從而增強代碼的可維護性和實用性。VRa%QxN
#IFudH~)pvgG@$(My53{}hZ"aewk
以下提供一個可供參考的Python項目結構(僅供參考,沒有硬性規定):nbzF=
nv(wdUx#s!}`^Bfy MHlm&6 )*%=
魚C大項目/ 來自:bbs.fishc.com
|----README/ 來自:bbs.fishc.com
| |----readme.txt 2*mQi@#
| |---- LICENSE.txt |x1?"^Upb:
| |----requirents.txt `C'>IHm
| |----setup.py Powered by bbs.fishc.com
|----docs/ 版權屬於:bbs.fishc.com
| |----help.htmlPowered by bbs.fishc.com
| |----quickstart.html N+niE]gf5;
|----test/ 來自:bbs.fishc.com
| |----__init__.py mZ_w*OBK.D
| |----test_basic.py M2)W{
| |----test_advanced.py [1a]3'~
|----package/ 版權屬於:bbs.fishc.com
| |----__init__ .py O_GX{ZfwV
| |----moduleA.py 1L0U;aOD=
| |----moduleB.py "slNHu
| |----moduleC.py fS|K`3?8
| |--- -static/ 來自:bbs.fishc.com
| | |----images/ y|.rV0{pMe
| | |----sounds/ A*=ctQ
|----setup.py來自:bbs.fishc.com
2.請寫下這一節課你學習到的內容:格式不限,回憶並複述是加強記憶的好方式!
小甲魚希望你認真對待作業就像你希望小甲魚推出高質量視頻一樣渴望^_^
上一節課我們已經基本介紹了模塊的作用以及用法,我們現在來簡單回顧一下(溫故而知新,可以為師矣),模塊的主要作用有哪些呢?
封裝、組織Python的代碼:當代碼量非常大的時候,我們可以有組織、有紀律的根據不同的功能將代碼分割為不同的模塊,這樣,每個模塊之間互相就是分隔開的、獨立開的,那大家想想,代碼是分開了容易閱讀和測試還是放在一起好?我們當然是更願意去閱讀和測試一小段代碼,而不是一來就劈頭蓋臉把整個程序讀起。
模塊的第二個作用就是實現代碼的重用,比如說你寫了一段發送郵件的代碼,多次調試、優化之後你覺得這段代碼非常棒了,那你可以將這段代碼封裝成一個獨立的模塊,那以後在任何程序需要發送郵件的時候,只要導入這個模塊,調用相關的函數就可以實現了,而不是說每一次都重複寫相同的代碼。
(一)我們這一講接著談談模塊,第一個內容是:
if __name__ == '__main__'
相信大部分人在讀別人的Python代碼的時候,都會看到這麼一句代碼,但是卻不知道有什麼用,那今天我就來給大家解惑啦,我們先來舉個例子吧:
還是上節課溫度轉換的例子,一般我們在寫了一個模塊之後,我們會單獨對這個模塊進行測試,因為一個大程序會有許多的模塊,我們應該每個模塊獨立寫完之後,在後面寫一個獨立的test(),對這個模塊的功能進行測試,而不是組裝起來才測試,那就很難調試了。對於這個溫度轉換的模塊,我們這裡的測試就是對前面兩個函數進行調用,如果正確,那就OK了
我們在模塊裡調用test(),然後模塊就可以直接運行了。
-
-
-
-
-
-
-
-
print("测试,0摄氏度 = %.2f华氏度"%c2f(0))
-
print("测试,0华氏度 = %.2f摄氏度"%f2c(0))
-
運行結果:
-
-
====== RESTART: C:\Users\XiangyangDai\Desktop\TemperatureConversion.py ======
-
-
經過測試,模塊的功能是沒問題的,然後我們在calc.py 這段源代碼裡面調用這個模塊的話:
-
-
sys.path.append("C:\\Users\\XiangyangDai\\Desktop")
-
import TemperatureConversion as tc
-
-
print("32摄氏度 = %.2f华氏度"%tc.c2f(32))
-
print("99华氏度 = %.2f摄氏度"%tc.f2c(99))
運行結果:
-
-
=============== RESTART: C:\Users\XiangyangDai\Desktop\calc.py ===============
-
-
-
-
Python就不自覺的把模塊中的測試代碼也給打印出來了,那這並不是我們想要的啊,那麼這種情況該怎麼去避免呢?
避免這種情況的關鍵在於讓Python知道該模塊是作為程序運行還是導入到其他程序中,為了實現這一點,你就需要使用__name__變量,
如果是在主程序裡面使用這個__name__變量的話,那得到的是個"__main__"
如果是在模塊中調用 這個__name__變量的話,那得到的就是這個模塊的名字。
-
-
-
-
-
這樣的話,你就不難理解這個 if __name__ == '__main__'這句代碼的意思了。
所以在上面的模塊的測試文件中,需要這樣改寫:
-
-
-
-
-
-
-
-
print("测试,0摄氏度 = %.2f华氏度"%c2f(0))
-
print("测试,0华氏度 = %.2f摄氏度"%f2c(0))
-
-
if __name__ == "__main__":
-
也就是說,只有在直接運行該模塊代碼時(也就是測試模塊的時候),__name__ 才等於"__main__",這時才運行test(),打印測試結果,當調用該模塊時, __name__ 是等於"模塊名"的,就不會打印測試結果了。
(二)我們接下來探索第二個問題:搜索路徑
像我們遇到一個問題:寫好的模塊應該擺在哪裡?有人說,“上節課你不是說應該放在和導入模塊的文件的源文件放在同一個文件夾嗎”,這是一個方案,你要調用哪個模塊,導入哪個模塊,把他們全部放在Python模塊的文件夾下,但是有的人就說了,“我並不喜歡把所有的程序放在同一個文件夾下,我想通過文件夾的形式更好的組織我的代碼”,這是可以實現的,但是在此之前,你必須先理解搜索路徑這個概念。
Python模塊的導入需要一個路徑搜索的過程,也就是說,你導入一個叫做hello 的模塊,Python會在預定義好的搜索路徑裡面找一個叫做hello.py 的模塊文件,如果有,則導入模塊,如果沒有,則導入失敗,而這個搜索路徑呢,就是一個列表,一組目錄,我們可以sys 模塊中的path 變量把它顯示出來:
-
-
-
['D:\\ProgramFiles\\Anaconda3\\Lib\\idlelib', 'D:\\ProgramFiles\\Anaconda3\\python35.zip', 'D:\\ProgramFiles\\Anaconda3\\DLLs', 'D:\\ProgramFiles\\Anaconda3\\lib', 'D:\\ProgramFiles\\Anaconda3', 'D:\\ProgramFiles\\Anaconda3\\lib\\site-packages', 'D:\\ProgramFiles\\Anaconda3\\lib\\site-packages\\Sphinx-1.4.6-py3.5.egg', 'D:\\ProgramFiles\\Anaconda3\\lib\\site-packages\\win32', 'D:\\ProgramFiles\\Anaconda3\\lib\\site-packages\\win32\\lib', 'D:\\ProgramFiles\\Anaconda3\\lib\\site-packages\\Pythonwin', 'D:\\ProgramFiles\\Anaconda3\\lib\\site-packages\\setuptools-27.2.0-py3.5.egg']
sys是與系統相關的模塊,Python會從上面的路徑中一個一個的去搜索有沒有相關的模塊。這裡需要解釋的是,不同的系統的sys.path顯示的路徑是不一樣的,這裡最佳的存放模塊的位置是'...\\lib\\site-packages',該文件夾本來就是設置類存放模塊的。
另外,按照這裡邏輯來說,你只需要告訴Python 你的模塊文件在哪裡找,Python在導入模塊的時候就可以正確找到,例如:我們想把桌面上的一個模塊導入,我們直接導入的話,是找不到的,因為桌面的路徑是不屬於sys.path 的搜索路徑的,我們就可以把桌面路徑加到搜索路徑中去。
-
-
sys.path.append("C:\\Users\\XiangyangDai\\Desktop")
這時候,再導入就不會出錯了,對於其他任意的文件夾,都可以這樣操作。
(三)接下來談最後一個概念:包(package)
在實際開發中,一個大型的系統通常有成千上萬個Python模塊,那麼使用模塊定義Python的功能還是遠遠不夠的,因為如果你把這些模塊全部放在一起,那你想想看,成千上萬個文件放在一個文件夾是什麼概念,非常亂,非常糟糕,而且還會有命名衝突的可能,那麼因此呢,Python中也出現了包的概念,什麼是包呢,其實就像我們剛才做的,把模塊分門別類的放到不同的文件夾,然後把各個文件夾的位置告訴Python。但是包的做法更加簡潔,創建一個包也非常簡單,步驟如下:
1、創建一個文件夾,用於存放相關的模塊,文件夾的名字就是包的名字;
例如,我們這裡創建一個文件夾M1,然後把模塊扔進去:
2、在文件夾中創建一個__init__.py 的模塊文件,內容可以為空:
3、將相關的模塊放入文件夾中(在第一步中我們就已經放進去了)。
在第2步中,必須在包目錄下創建一個__init__.py的模塊,你可以是一個空文件,但是必須要有這個文件,因為這是Python的規定,用來告訴Python,把這個文件夾(這個目錄)當做一個包來管理。
接下來,要導入包的模塊,怎麼導?其實也很簡單,就是使用包名.模塊名來導入就可以了
-
-
sys.path.append("C:\\Users\\XiangyangDai\\Desktop")
-
import M1.TemperatureConversion as tc
-
-
print("32摄氏度 = %.2f华氏度"%tc.c2f(32))
-
print("99华氏度 = %.2f摄氏度"%tc.f2c(99))
-
-
-
=============== RESTART: C:\Users\XiangyangDai\Desktop\calc.py ===============
-
-
0 留言:
發佈留言