Python_3.ppt_第1页
Python_3.ppt_第2页
Python_3.ppt_第3页
Python_3.ppt_第4页
Python_3.ppt_第5页
已阅读5页,还剩43页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Python Tutorial 3,Laboratory for Reliable Computing Department of Electrical Engineering National Tsing Hua University Hsinchu, Taiwan,邢育肇 Yu-Tsao Hsing,2,Procedure (cont.),7/28 Python Tutorial (3) PM 1:004:00 6. Modules 7. Regular Task 8/4 Python Tutorial (4) PM 1:004:00 8. Exceptions 9. Classes,6.

2、 Modules,4,Why Modules?,程式碼的再使用 對話模式如果結束Python, 程式碼也會不見 模組可以讓我們把程式碼儲存在檔案裡 還可以reload 系統空間名稱分割 模組是Python裡最高層次的單元 萬人之上 是組織系統元件的工具 實作共享服務或共享資料 若有許多函式會使用相同的資料結構, 可以將此資料結構寫在module裡面, 再由各個函式自行匯入即可,5,基本概念,建立模組: 只要將程式碼寫到檔案裡, 存成.py即可 也可以是C延伸檔案 使用模組: Import:得到一整個完整的模組檔案 From:可以從某個模組檔案裡取出幾個特定的名稱 Reload:可重載模組的程式

3、碼而毋須跳離解譯程式 另外也可以直接於系統下執行 模組搜尋路徑: Python搜尋模組檔案時, 會檢視存於PYTHONPATH環境參數中的目錄路徑 可以藉由改變模組sys裡面的path來更動,6,基本範例,模組可以使用任何一種文書編輯軟體來編輯 請一定要以.py作為結尾 檔案的名稱一樣受到命名規則的規範 無法匯入if.py的模組 Ex. 有一個名為larc.py的模組檔案 def printer(x): #模組屬性 print x %python #進入python,7,基本範例, import larc #得到模組 larc.printer(Hello python!) #以評定用法取出名稱

4、 Hello python! from larc import printer #得到一次釋出 printer(Hello python!) #不需要評定取出名稱 Hello python! from larc import * #得到全部的釋出 printer(Hello python!) Hello python!,8,模組檔案=名稱空間,模組的敘述在第一次匯入時執行 python會建立一個空的模組物件 從頭到尾執行一遍 最高層次的指定運算建立模組屬性 由原先模組裡最高層次的=, def來建立 由=建立成員變數, def建立成員函式 指定的名稱會存在模組的名稱空間裡 模組名稱空間:_dic

5、t_ 模組匯入時建立的名稱空間是辭典 模組是獨立的範圍 使用必需使用評定方式 載入之後一直可以使用 與函式只有在執行時存在名稱空間不一樣,9,基本範例二,Ex. 有一個名為larc.py的模組檔案 import sys name = 42 def func(): pass print done loading. import larc.py done loading. larc.sys 42 larc.func larc._dict_.keys() _file_, name, _name_, #_file_:模組的檔案名稱 sys, _doc_, _builtins_, f

6、unc #_name_:模組名稱,10,名稱評定用法,簡單變數 “X”意指在當前的範圍裡搜尋名稱X(LGB法則) 評定用法 “X.Y”意指在X物件中搜尋屬性Y(not範圍) 評定用法路徑 “X.Y.Z”意指在X物件中搜尋Y, 然後在物件X.Y中搜尋Z 跟之前的範圍法則毫無關係 LGB法則只對無評定用法的名稱生效而已 可以將它想像成一個連結到另一個名稱空間的指標 評定用法適用於所有有屬性的物件 模組, 類別皆適用 也算是類別裡繼承(inheritance)的實作,11,匯入模式,匯入只發生一次 模組在第一次使用import或from時會載入 執行模組的程式碼, 會使模組建立其名稱空間 之後任何的

7、import和from只會從已載入的模組存取東西 % cat simple.py spam = 1 %python import simple simple.spam 1 simple.spam = 2 import simple simple.spam 2,12,import和from,和def一樣, import和from都是可執行敘述, 所以都可以寫在if敘述內, or 函式內部 import和from也都是隱性的指定運算 import會把整個模組指定給一個名稱 from會把名稱指定給另一個模組中同樣名稱的物件 from module import *等同於下列程式 Import mod

8、ule name1 = 1 name2 = 2 del module,13,指定會碰到的問題,% cat small.py x = 1 y = 1,2 %python from small import x, y #複製兩個名稱出來 x = 42 #只改變區域的x y0 = 42 #改變共享的可變更物件 import small #得到模組名稱 small.x #small的x不是區域的x 1 smal.y #與區域共享一個可變更物件 42,2,14,reload()-introduction,import只會在第一次匯入模組時執行模組的程式碼 稍後

9、的import只會使用已載入的模組物件 reload函式會強迫已經載入的模組程式碼重新執行 reload是函式不是敘述 可以容許程式不中斷 並變更部分的程式碼 書寫格式 import module #匯入模組 #在此改變模組的程式碼 reload(module) #得到更新後的結果 ,15,reload()-詳細說明,reload會在模組的名稱空間裡重新執行模組的程式碼 會覆寫模組已存在的名稱空間 不是先刪除舊的名稱空間, 再載入一次 最高層次的指定運算會替換對映名稱的內容 會影響所有以import來取出模組名稱內容的程式 reload會替代所有之前位於模組名稱空間裡的數值 reload只會影

10、響重載之後的from敘述 若使用from來取出模組的屬性, 則reload並不會影響原先持有的數值內容 但是reload之後還有from敘述發生, 則程式得到的是新的內容,16,reload()-範例(1/2),%cat changer.py message = “1st version” def printer(): print message 先呼叫一次 %python import changer changer.printer() 1st version 新開一個視窗編輯changer.py %cat changer.py message = “2nd version”,回到Pytho

11、n解譯程式 import changer changer.printer() 1st version #沒有影響 重新載入模組 reload(changer) changer.printer() 2nd version #新的結果,17,模組編譯程式,python系統稱為解譯程式 其實較類似java,介於編譯程式與解譯程式之間 擁有中介形式:位元碼(bytecode) 擁有一個Visual Machine來執行bytecode bytecode程式儲存為.pyc副檔名 在import過後就會產生 對一個模組M來說 如果M.py在M.pyc儲存之後沒有任何的變更, 則python將改載入M.py

12、c而不是M.py 如果M.py有更動的話, 則會載入M.py並產生新的M.pyc覆蓋之前的版本 也可以將.pyc視為python程式的封裝版本 可擁有資料的隱密性,18,_name_和_main_,特殊情況: 名稱開頭有底線字元就不會被匯入 減少名稱空間多餘的匯入 每一個模組都有一個內建的屬性:_name_ 如果檔案當作程式來執行, _name_會設定成”_main_”字串 如果檔案當作模組來匯入, _name_會設定成模組的名稱 _main_在自身測試上最常出現 %cat tester.py if _name_=_main_: print “This is a program” else:

13、print “This is a module”,%python import tester This is a module %python test.py This is a program,19,變更模組搜尋路徑,模組搜尋路徑存在PYTHONPATH的目錄裡 使用sys.path來改變搜尋路徑 import string sys.path ., c:pythonlib, c:pythonlibtkinter sys.path = ., c:bookexamples #改變搜尋路徑 sys.path ., c:bookexamples import string Traceback (in

14、nermost last): #因為將pythonlib的路徑刪了 File “”, line 1 , in ? ImportError: No module named string 不要亂刪除python原始的目錄路徑,20,模組設計的概念,到處都是模組 只要有程式碼, 就有模組 事實上, 對話模式也是建構在模組上, 檔名為_main_ 減少模組之間的對偶關係(coupling) 如同函式, 模組寫的越獨立, 運作的越好 若模組在另一個模組裡, 要做到不受該模組的廣域變數影響比較好 模組應該盡量不要更改別的模組的變數內容 也就是少發生goto的情形,21,恐怖的陷阱-from只複製名稱,%

15、cat module1.py X = 99 def printer(): print X %python from module1 import X, printer X= 88 printer() 99 解決方法: 使用import方法, 不要用from import module1 module1.X = 88 module1.printer() 88,22,恐怖的陷阱-程式碼的先後次序,由於模組第一次匯入時, 就會從頭到尾執行一次, 所以會有幾個問題: 位於模組最高層次的程式碼(即不在函式or巢狀敘述裡的部份)在匯入時就會立刻被執行, 因此這些程式碼絕對不能參考到檔案後面才指定的名稱 位

16、於函式主體的程式碼只有當函式被呼叫時才會執行, 所以在呼叫前其名稱空間並不存在, 通常可以參考檔案裡的任何名稱 func1() #錯誤: “func1”尚未指定 def func1(): print func2(): #沒問題: “func2”稍後才會搜尋 func1() #錯誤: “func2”尚未指定 def func2(): return “Hello” func1() #沒問題:“func1”和“func1”都指定了 解決方法: 請把def敘述放在檔案最前頭, 把最高層次的程式碼放在檔案的尾部,23,恐怖的陷阱-from的遞迴匯入,匯入必須從頭到尾執行一次 模組之間彼此互相匯入, 會有

17、問題 若模組在匯入另一個模組時, 模組還沒有執行完全, 使得有一些名稱沒有指定到 %cat recur1.py X = 1 #正確:有執行 import recur2 #錯誤:recur2不存在 Y = 2 #未執行 %cat recur2.py from recur1 import X #正確:“X”已經指定了 from recur1 import Y #錯誤:“Y”尚未指定 解決方法: 歹路不可行阿 盡量減少模組循環的次數, 降低模組依存的關係 如果一定要, 請延緩模組名稱的存取, 或是擺到函式裡執行,24,恐怖的陷阱-reload會敗給from,萬惡的淵藪:from 由於from只會將名

18、稱複製過去, 等於此名稱和原來的模組失去了聯繫 reload的重載對from完全無影響力 算是module狀態的goto 如果你的module常常變動需要reload, 請不要用from from使用的時機: 只使用一個大模組裡的小函式(節省記憶體) 小module, 且不常變動(方便不需評定),25,恐怖的陷阱-reload只有一次,當reload時候, python只會重載那個指定的模組檔案, 如果內部還有匯入模組的敘述, python會當作沒看到 %cat A.py import B import C %python reload A 只會reload A, B和C不會重載一次 解決方法

19、: 最好不要這樣搞 目前學的撇步裡面沒這招!(還是有解的拉),7. Regular Task,27,Outline,copy的深入探討 辭典的複製 copy模組 排序 隨機存取 檔案 呼叫程式 資源,28,辭典的複製,串列的複製 newlist = oldlist : 整個切下來複製給newlist tuple也是相同的作法 辭典的複製(1) newDic = for key in oldDic.keys( ): newDickey = oldDickey 辭典的複製(2)(after ver 1.5) newDic = oldDic.copy( ),29,辭典的複製-進階(1/3),如果有一

20、個辭典Dic, 你想把Dic的某些內容替換成另一個辭典otherDic 假設 Dic = micheal:555-1212, emily:556-0091 otherDic = latoya:555-1255, emily:667-1234 最簡單的作法:update() Dic.update(otherDic) 也可以自己寫 for key in otherDic.keys(): Dickey = otherDickey Dic micheal:555-1212, latoya:555-1255, emily:667-1234,30,辭典的複製-進階(2/3),如果你希望兩者不要有覆蓋的問題

21、 解決方法1:遇到覆蓋的部份就跳出 def MergeWithoutOverlap(Dic, otherDic): newDic = Dic.copy( ) for key in otherDic.keys( ): if key in Dic.keys( ): print “the two dictionaries are sharing keys!” return 0 newDickey = otherDickey return newDic newDic = MergeWithoutOverlap(Dic, otherDic) “the two dictionaries are shari

22、ng keys!”,31,辭典的複製-進階(3/3),解決方法2:如果有覆蓋, 就存成tuple def MergeWithOverlap(Dic, otherDic): newDic = Dic.copy( ) for key in otherDic.keys( ): if key in Dic.keys( ): newDickey = Dickey, otherDickey else newDickey = otherDickey return newDic newDic = MergeWithOverlap(Dic, otherDic) newDic emily:(556-0091, 6

23、67-1234), micheal:555-1212, latoya:555-1255,32,copy模組,+0, + , :, .copy可以處理數值, 字串, 串列, 辭典複製的問題, 不過python仍然有通用的函式可以使用 copy模組: copy( ):與之前的複製一樣, 只複製最上層 deepcopy( ):連內部巢狀資料皆複製 import copy list1 = name:larc, dept.:ee, 1, tw, 3.0 list2 = copy.copy(list1) list3 = copy.deepcopy(list1) list1.append(nthu) lis

24、t10dept. = eecs print list1; print list2; print list3 name:larc, dept.:eecs, 1, tw, 3.0, nthu name:larc, dept.:eecs, 1, tw, 3.0 name:larc, dept.:ee, 1, tw, 3.0,33,排序(1/2),只有串列擁有sort的內建函式 其他人呢? tuple的排序:使用list( )轉成串列 newList = list(oldTuple) newList.sort( ) 辭典的排序: newList = oldDic.keys( ) newList.sor

25、t( ) sort用的是python內建的比較方法 我們可以定義自己的比較函式 只要給定兩個物件, 會傳回-1, 0, 1分別代表即可 將此比較函式設為sort的引數,34,排序(2/2),做一個不管大小寫的排序方式 def FreeSort(one, two): from string import lower one, two = lower(one), lower(two) return cmp(one, two) testList = this, is, A, sorted, List testList.sort() print testList A, List, is, sorted

26、, this testList.sort(FreeSort) print testList A, is, List, sorted, this,35,random模組,最常使用的是choice( ) 給定一個串列, 它就會隨機挑出其中一個物件 若不需要挑出重複物件, 請在挑完後移除該物件即可 隨機列印出串列裡所有的物件: from random import choice while list1: element = choice(list1) list1.remove(element) print element ,36,檔案-sys(1/3),三種資料流 sys.stdin:標準輸入 sy

27、s.stdout:標準輸出, 也是print的輸出點 sys.stderr:標準錯誤 範例一:count.py import sys data = sys.stdin.readlines() print “There are”, len(data), “lines in this file.” % cat count.py | python count.py There are 3 lines in this file.,37,檔案-sys(2/3),範例二:把開頭#字元的每一列找出來 import sys for line in sys.stdin.readlines(): if line0

28、 = #: print line 範例三:印出前十列, 後十列, 隔列 import sys, string lines = sys.stdin.readlines() sys.stdout.writelines(lines:10) #首十列 for lineIndex in range(0, len(lines), 2): #取出0,2,4. sys.stdout.write(lineslineIndex) #取出索引列,38,檔案-sys(3/3),範例四:轉置矩陣 import sys, string lines = sys.stdin.readlines() wordlists = f

29、or line in lines: words = string.split(line) wordlists.append(words) for row in range(len(wordlists0): for col in range(len(wordlists): print wordlistscolrow + t, print,39,檔案-一次讀一點,一次讀取一字元 While 1: next = sys.stdin.read(1) #讀出一個字元的字串 if not next: #遇到EOF就跳出 break #處理next 一次讀取一列 while 1: next = sys.stdin.readline() #讀出一列的字串 if not next: #遇到EOF就跳出 break #處理next,40,呼叫程式,python可以當成命令稿語言來使用 os.system(命令列字串) 直接呼叫外部程式, 也在外部執行 輸出使用標準輸出 for filename in 001.data, 002.data: os.system(“cp ”+filename+” /”) 輸出

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论