Python編程從入門到實戰(zhàn)-輕松過二級 (思政版)(第2版) 課件 Ch10 模塊和模塊化程序設(shè)計_第1頁
Python編程從入門到實戰(zhàn)-輕松過二級 (思政版)(第2版) 課件 Ch10 模塊和模塊化程序設(shè)計_第2頁
Python編程從入門到實戰(zhàn)-輕松過二級 (思政版)(第2版) 課件 Ch10 模塊和模塊化程序設(shè)計_第3頁
Python編程從入門到實戰(zhàn)-輕松過二級 (思政版)(第2版) 課件 Ch10 模塊和模塊化程序設(shè)計_第4頁
Python編程從入門到實戰(zhàn)-輕松過二級 (思政版)(第2版) 課件 Ch10 模塊和模塊化程序設(shè)計_第5頁
已閱讀5頁,還剩42頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第二版本章要點:模塊化程序設(shè)計的概念模塊的設(shè)計和實現(xiàn)包名稱空間與名稱查找順序應(yīng)用舉例:基于模塊的庫存管理系統(tǒng)第10章模塊和模塊化程序設(shè)計10.1模塊化程序設(shè)計的概念如果程序中包含多個可以復(fù)用的函數(shù)或類,則通常把相關(guān)的函數(shù)和類分組包含在單獨的模塊(module)中。這些提供計算功能的模塊稱之為模塊(或函數(shù)模塊),導入并使用這些模塊的程序,則稱之為客戶端程序把計算任務(wù)分離成不同模塊的程序設(shè)計方法,稱之為模塊化編程(modularprogramming)。使用模塊,可以將計算任務(wù)分解為大小合理的子任務(wù),并實現(xiàn)代碼的重用功能模塊的API(1)API用于描述模塊中提供的函數(shù)的功能和調(diào)用方法客戶端使用模塊提供的函數(shù)時,無須了解其實現(xiàn)細節(jié)模塊和客戶端之間遵循的契約稱之為API(ApplicationProgrammingInterface,應(yīng)用程序編程接口)10.2模塊的設(shè)計和實現(xiàn)模塊的API(2)模塊化程序設(shè)計的基本原則是先設(shè)計API(即模塊提供的函數(shù)或類的功能描述),然后實現(xiàn)API(即編寫程序,實現(xiàn)模塊函數(shù)或類),最后在客戶端中導入并使用這些函數(shù)或類通過內(nèi)置函數(shù)help(),可以查看Python模塊的API【例10.1】通過內(nèi)置函數(shù)help()查看math模塊的API>>>importmath>>>help(math)【例10.2】通過Python在線幫助查看math模塊的API(1)運行Python內(nèi)置集成開發(fā)環(huán)境IDLE(2)打開PythonDocs。執(zhí)行IDLE菜單命令Help|PythonDocs,打開Python幫助文檔(3)定位到math模塊,查看其API模塊的實現(xiàn)“實現(xiàn)”是指實現(xiàn)用于重用的函數(shù)或類的代碼,模塊的實現(xiàn)就是若干實現(xiàn)函數(shù)或類的代碼的集合,保存在一個后綴為.py的文件中模塊的實現(xiàn)必須遵循API規(guī)約,可以采用不同算法實現(xiàn)API,這為模塊的改進和版本升級提供了無縫對接,只需要使用遵循API的新的實現(xiàn),所有客戶端程序無須修改即可以正常運行模塊的客戶端客戶端遵循API提供的調(diào)用接口,導入和調(diào)用模塊中實現(xiàn)的函數(shù)功能API允許任何客戶端直接使用模塊,而無需檢測模塊中定義的代碼,例如可以直接使用模塊math和random模塊的客戶端模塊的客戶端【例10.3】模塊的客戶端示例模塊的客戶端在[0,

]區(qū)間,均勻輸出函數(shù)y=sin(x)+sin(5x)所對應(yīng)的(n+1)個函數(shù)值。其中,n由命令行第一個參數(shù)所確定importmathimportsysn=int(sys.argv[1])foriinrange(n+1):x=math.pi*i/ny=math.sin(x)+math.sin(5*x)print(x,y)模塊化程序設(shè)計的優(yōu)越性可以編寫大規(guī)模的系統(tǒng)程序控制程序的復(fù)雜度實現(xiàn)代碼重用增強可維護性模塊設(shè)計的一般原則模塊的客戶端(1)先設(shè)計API,再實現(xiàn)模塊(2)控制模塊的規(guī)模,只為客戶端提供需要的函數(shù)。實現(xiàn)包含大量函數(shù)的模塊會導致模塊的復(fù)雜性。例如,Python的math模塊中就不包含正割函數(shù)、余割函數(shù)和余切函數(shù),因為這些函數(shù)很容易通過函數(shù)math.sin()、math.cos()和math.tan()的計算而得(3)在模塊中編寫測試代碼,并消除全局代碼(4)使用私有函數(shù)實現(xiàn)不被外部客戶端調(diào)用的模塊函數(shù)(5)通過文檔提供模塊幫助信息API設(shè)計模塊的客戶端API定義客戶端和實現(xiàn)之間的契約。API是一個明確的規(guī)范,規(guī)定“實現(xiàn)”的具體功能是什么API通常由兩部分組成:可用函數(shù)的簽名的精確規(guī)范,以及描述函數(shù)作用的非正式自然語言描述。API一般使用表格的形式,描述模塊中的變量、函數(shù)和類當編寫一個新模塊時,建議先設(shè)計API,然后實現(xiàn)模塊【例10.4】設(shè)計實現(xiàn)算術(shù)四則運算的模塊(my_math1.py)的API創(chuàng)建模塊模塊的客戶端Python模塊對應(yīng)于包含Python代碼的源文件(其擴展名為.py),在文件中可以定義變量、函數(shù)和類在模塊中,除了可以定義變量、函數(shù)和類之外,還可以包含一般的語句,稱之為主塊(全局語句)。當運行該模塊,或?qū)朐撃K時,主塊語句將依次執(zhí)行模塊的客戶端【例10.5】創(chuàng)建模塊my_math1.pyPI=3.14#定義常量defadd(x,y):#定義函數(shù)

returnx+y#加defsub(x,y):#定義函數(shù)

returnx-y#減defmul(x,y):#定義函數(shù)

returnx*y#乘defdiv(x,y):#定義函數(shù)

returnx/y#除在模塊中定義了算術(shù)四則運算模塊的私有函數(shù)模塊的客戶端實現(xiàn)模塊時,有時候需要在模塊中定義僅在模塊中使用的輔助函數(shù)。輔助函數(shù)不提供給客戶端直接調(diào)用,故稱之為私有函數(shù)按慣例,Python程序員使用下劃線開始的函數(shù)名作為私有函數(shù)。私有函數(shù)客戶端不應(yīng)該直接調(diào)用,故API中不包括私有函數(shù)Python語言沒有強制不允許調(diào)用私有函數(shù)的機制,程序員應(yīng)該避免直接調(diào)用私有函數(shù)模塊的客戶端【例10.6】創(chuàng)建模塊normal.py,實現(xiàn)正態(tài)分布的概率密度函數(shù)PDFimportmathdef_phi(x):returnmath.exp(-x*x/2.0)/math.sqrt(2*math.pi)defpdf(x,mu=0.0,sigma=1.0):return_phi(float((x-mu)/sigma))/sigma#測試代碼if__name__=='__main__':#如果獨立運行時,則運行測試代碼

foriinrange(0,101):print(i,pdf(i,mu=78,sigma=10))模塊的測試代碼模塊的客戶端每個模塊都有一個名稱,通過特殊變量__name__可以獲取模塊的名稱特別地,當一個模塊被用戶單獨運行時,其__name__的值為'__main__'。故可以把模塊源代碼文件的測試代碼寫在相應(yīng)的測試判斷中,以保證只有單獨運行時,才會運行測試代碼模塊的客戶端【例10.7】創(chuàng)建模塊my_math2.pyPI=3.14#定義常量defadd(x,y):#定義函數(shù)

returnx+y#加defsub(x,y):#定義函數(shù)

returnx-y#減defmul(x,y):#定義函數(shù)

returnx*y#乘defdiv(x,y):#定義函數(shù)

returnx/y#除#測試代碼defmain():print('123+456=',add(123,456))#加

print('123-456=',sub(123,456))#減

print('123*456=',mul(123,456))#乘

print('123/456=',div(123,456))#除if__name__=='__main__':#如果獨立運行時,則運行測試代碼

main()測試代碼只有獨立運行時才執(zhí)行編寫模塊文檔字符串模塊的客戶端在函數(shù)的第一個邏輯行的字符串稱為函數(shù)的文檔字符串。函數(shù)的文檔字符串用于提供有關(guān)函數(shù)的幫助信息文檔字符串一般遵循下列慣例:文檔字符串是一個多行字符串;首行以大寫字母開始,句號結(jié)尾;第二行是空行;從第三行開始是詳細的描述可以使用三種方法抽取函數(shù)的文檔字符串幫助信息:①使用內(nèi)置函數(shù):help(函數(shù)名);②使用函數(shù)的特殊屬性:函數(shù)名.__doc__;③第三方自動化工具也可以抽取文檔字符串信息,以形成幫助文檔模塊的客戶端【例10.8】查看文檔字符串示例幫助信息>>>help(abs)Helponbuilt-infunctionabsinmodulebuiltins:abs(x,/)Returntheabsolutevalueoftheargument.>>>print(abs.__doc__)#輸出:Returntheabsolutevalueoftheargument.模塊的客戶端【例10.9】文檔字符串示例"""doc模塊說明文檔"""#模塊注釋defd2b(i):#定義函數(shù)d2b()"""函數(shù)d2b()的說明文檔"""print(bin(i))classDoc:#定義類Doc"""類Doc的說明文檔"""defsayHello(self):#定義類Doc的方法sayHello()"""方法sayHello()的說明文檔"""print('hi')按字節(jié)編譯的.pyc文件模塊的客戶端.pyc文件是經(jīng)過編譯后的字節(jié)碼,這樣下次導入時,如果模塊源代碼.py文件沒有修改(通過比較兩者的時間戳),則直接導入.pyc文件,從而提高程序效率按字節(jié)編譯的.pyc文件是在導入模塊時,python解釋器自動完成,無需程序員手動編譯10.3包(1)功能相似的模塊使用包組成層次組織結(jié)構(gòu)【例10.10】包示例包(2)創(chuàng)建包在指定目錄中創(chuàng)建對應(yīng)包名的目錄在該目錄下創(chuàng)建一個特殊文件:__init__.py文件最后在該目錄下創(chuàng)建模塊文件【例10.11】創(chuàng)建包示例。在C:\pythonpa\ch10\目錄中,創(chuàng)建如下目錄結(jié)構(gòu):包(3)包的導入和使用import[包名1.[包名2.…]].模塊名#導入包中模塊[包名1.[包名2.…]].模塊名.函數(shù)名#使用全限定名稱調(diào)用模塊中的成員from[包名1.[包名2.…]].模塊名import成員名#導入模塊中的具體成員from包名import*【例10.12】包的導入和使用>>>fromxml.domimportminidom>>>doc=minidom.Document()10.4名稱空間與名稱查找順序在Python程序中,每一個名稱(變量名、函數(shù)名或類型名)都有一個作用范圍。在其作用范圍之內(nèi),可以直接引用該名稱;在其作用范圍之外,該名稱不存在,引用該名稱將導致一個錯誤NameError。則這個作用范圍稱為名稱空間,也稱為命名空間當代碼中使用名稱x時,Python解釋器把x解釋為對象名(對象、函數(shù)、變量等),并按如下名稱空間順序查找以x命名的對象:(1)局部名稱空間。當前函數(shù)或類的方法中定義的局部變量(2)全局名稱空間。當前的模塊(.py文件)中定義的變量、函數(shù)或類(3)內(nèi)置名稱空間。對每個模塊都是全局的。作為最后的嘗試,Python將假設(shè)x是內(nèi)置函數(shù)或變量【例10.13】名稱查找示例>>>math.e#報錯。NameError:name'math'isnotdefined>>>importmath>>>math.e#輸出:2.71828182845904510.5應(yīng)用舉例:基于模塊的庫存管理系統(tǒng)庫存管理系統(tǒng)API設(shè)計本節(jié)實現(xiàn)一個簡單的基于模塊的庫存管理系統(tǒng)。系統(tǒng)采用JSON文件來保存數(shù)據(jù)。產(chǎn)品信息設(shè)計為字典,鍵為sku_id(產(chǎn)品ID),值為sku_name(產(chǎn)品名稱),使用products.json實現(xiàn)其持續(xù)化。貨架位置信息也設(shè)計為字典,鍵為loc_id(貨架ID),值為loc_name(貨架名稱),使用location.json實現(xiàn)其持續(xù)化。商品庫存信息設(shè)計為列表[sku_id,loc_id]的列表,使用items.json實現(xiàn)其持續(xù)化庫存管理系統(tǒng)設(shè)計為三個模塊文件,即data.py、ui.py和main.py庫存管理系統(tǒng)ui.py負責用戶界面交互,其API設(shè)計如表10-3所示庫存管理系統(tǒng)data.py模塊的API庫存管理系統(tǒng)的功能設(shè)計(1)庫存信息管理系統(tǒng)主要包括如下功能。(1)產(chǎn)品信息報表調(diào)用ui.report_products(),顯示產(chǎn)品信息列表。(2)增加產(chǎn)品信息調(diào)用mpt_for_new_sku_id(),提示用戶輸入新的產(chǎn)品ID,調(diào)用mpt_for_sku_name(),提示用戶輸入產(chǎn)品名稱。調(diào)用data.add_product(sku_id,sku_name)增加新的產(chǎn)品。如果用戶輸入為空,則返回None,即什么也不做。(3)貨架位置報表調(diào)用ui.report_location(),顯示貨架位置信息列表。(4)增加貨架位置調(diào)用mpt_for_new_loc_id(),提示用戶輸入新的貨架位置ID,調(diào)用mpt_for_loc_name(),提示用戶輸入貨架名稱。調(diào)用data.add_location(sku_id,sku_name)增加新的貨架。如果用戶輸入為空,則返回None,即什么也不做庫存管理系統(tǒng)的功能設(shè)計(2)(5)商品庫存信息報表調(diào)用ui.report_items(),顯示庫存信息列表。(6)商品入庫管理調(diào)用mpt_for_old_sku_id(),提示用戶輸入產(chǎn)品ID,調(diào)用mpt_for_old_loc_id(),提示用戶輸入貨架ID。調(diào)用data.add_item(sku_id,loc_id),實現(xiàn)商品入庫。如果用戶輸入為空,則返回None,即什么也不做。(7)商品出庫管理調(diào)用mpt_for_old_sku_id(),提示用戶輸入產(chǎn)品ID,調(diào)用mpt_for_old_loc_id(),提示用戶輸入貨架ID。調(diào)用data.remove_item(sku_id,loc_id),實現(xiàn)商品出庫。如果庫存不存在,則報錯。如果用戶輸入為空,則返回None,即什么也不做主模塊main.py的實現(xiàn)(1)主模塊導入data和ui模塊。在main.py中,定義main()函數(shù),首先調(diào)用data.init(),從磁盤JSON格式文件中讀取數(shù)據(jù)。然后在無限循環(huán)中,調(diào)用mpt_for_action()顯示功能菜單,接受用戶輸入,并根據(jù)用戶的功能選擇,實現(xiàn)各模塊相應(yīng)功能"""庫存管理系統(tǒng):基于JSON"""importdataimportuidefmain():data.init()whileTrue:action=mpt_for_action()ifaction=='QUIT':breakelifaction=='REPORT_PRODUCTS':ui.report_products()elifaction=='ADD_PRODUCT':sku_id=mpt_for_new_sku_id()ifsku_id!=None:sku_name=mpt_for_sku_name()ifsku_name!=None:data.add_product(sku_id,sku_name)主模塊main.py的實現(xiàn)(2)elifaction=='REPORT_LOCATIONS':ui.report_locations()elifaction=='ADD_LOCATION':loc_id=mpt_for_new_loc_id()ifloc_id!=None:loc_name=mpt_for_loc_name()ifloc_name!=None:data.add_location(loc_id,loc_name)elifaction=='REPORT_ITEMS':ui.report_items()elifaction=='ADD_ITEM':sku_id=mpt_for_old_sku_id()ifsku_id!=None:loc_id=mpt_for_old_loc_id()ifloc_id!=None:data.add_item(sku_id,loc_id)elifaction=='REMOVE_ITEM':sku_id=mpt_for_old_sku_id()ifsku_id!=None:loc_id=mpt_for_old_loc_id()ifloc_id!=None:ifnotdata.remove_item(sku_id,loc_id):print('該庫存不存在')#######################################################################if__name__=="__main__":main()用戶界面交互模塊ui.py的實現(xiàn)(1)【例10.15】庫存管理系統(tǒng)用戶界面交互模塊ui.pyimportdatadefprompt_for_action():"""提示功能菜單。返回用戶輸入選擇"""whileTrue:print('---------------庫存信息管理系統(tǒng)-------------')print('|1:產(chǎn)品信息報表|')print('|2:增加產(chǎn)品信息|')print('|3:貨架位置報表|')print('|4:增加貨架位置|')print('|5:商品庫存信息報表|')print('|6:商品入庫管理|')print('|7:商品出庫管理|')print('|0:退出|')print('-------------------------------------------')choice=input('請選擇功能菜單(0-7):')ifchoice=='0':return'QUIT'elifchoice=='1':return'REPORT_PRODUCTS'elifchoice=='2':return'ADD_PRODUCT'elifchoice=='3':return'REPORT_LOCATIONS'elifchoice=='4':return'ADD_LOCATION'elifchoice=='5':return'REPORT_ITEMS'elifchoice=='6':return'ADD_ITEM'elifchoice=='7':return'REMOVE_ITEM'defreport_products():"""產(chǎn)品信息報表"""for(k,v)indata.get_products().items():print('{0:8}{1}'.format(k,v))defprompt_for_old_sku_id():"""提示用戶輸入有效的產(chǎn)品sku_id并返回有效產(chǎn)品ID,或者返回None"""whileTrue:sku_id=input("請輸入產(chǎn)品ID:")ifsku_id=="":returnNoneelifsku_idnotindata.get_products():print("該產(chǎn)品不存在,請重新輸入")用戶界面交互模塊ui.py的實現(xiàn)(2)else:returnsku_iddefprompt_for_new_sku_id():"""提示用戶輸入新的產(chǎn)品sku_id并返回新產(chǎn)品ID,或者返回None"""whileTrue:sku_id=input("請輸入新的產(chǎn)品ID:")ifsku_id=="":returnNoneelifsku_idindata.get_products():print("該產(chǎn)品已經(jīng)存在,請重新輸入")else:returnsku_iddefreport_locations():"""貨架位置報表"""for(k,v)indata.get_locations().items():print('{0:8}{1}'.format(k,v))defprompt_for_old_loc_id():"""提示用戶輸入有效的貨架位置loc_id并返回有效貨架位置ID,或者返回None"""用戶界面交互模塊ui.py的實現(xiàn)(3)whileTrue:sku_id=input("請輸入產(chǎn)品ID:")ifsku_id=="":returnNoneelifsku_idnotindata.get_products():print("該產(chǎn)品不存在,請重新輸入")else:returnsku_iddefprompt_for_new_sku_id():"""提示用戶輸入新的產(chǎn)品sku_id并返回新產(chǎn)品ID,或者返回None"""whileTrue:sku_id=input("請輸入新的產(chǎn)品ID:")ifsku_id=="":returnNoneelifsku_idindata.get_products():print("該產(chǎn)品已經(jīng)存在,請重新輸入")else:returnsku_id用戶界面交互模塊ui.py的實現(xiàn)(4)defreport_locations():"""貨架位置報表"""for(k,v)indata.get_locations().items():print('{0:8}{1}'.format(k,v))defprompt_for_old_loc_id():"""提示用戶輸入有效的貨架位置loc_id并返回有效貨架位置ID,或者返回None"""whileTrue:loc_id=input("請輸入貨架位置ID:")ifloc_id=="":returnNoneelifloc_idnotindata.get_locations():print("該貨架位置不存在,請重新輸入")else:returnloc_iddefprompt_for_new_loc_id():"""提示用戶輸入新的貨架位置loc_id并返回,或者返回None"""用戶界面交互模塊ui.py的實現(xiàn)(5)whileTrue:loc_id=input("請輸新的貨架位置ID:")ifloc_id=="":returnNoneelifloc_idindata.get_locations():print('該貨架位置已經(jīng)存在,請重新輸入')else:returnloc_iddefprompt_for_sku_name():"""提示用戶輸入產(chǎn)品名稱sku_name并返回產(chǎn)品名稱,或者返回None"""whileTrue:sku_name=input("請輸入產(chǎn)品名稱:")ifsku_name=="":returnNoneelse:returnsku_namedefprompt_for_loc_name():"""提示用戶輸入貨架位置名稱loc_name并返回貨架位置名稱,或者返回None"""用戶界面交互模塊ui.py的實現(xiàn)(6)whileTrue:loc_name=input("請輸入貨架位置名稱:")ifloc_name=="":returnNoneelse:returnloc_namedefreport_items():"""庫存信息報表"""for(k,v)indata.get_items():sku_name=data.get_products()[k]loc_name=data.get_locations()[v]print('{0:8}{1}:{2:8}{3}'.format(k,sku_name,v,loc_name))用戶界面交互模塊ui.py的實現(xiàn)(7)importosimportjson#全局變量_products={}#保存產(chǎn)品信息的字典:sku_id:sku_name_locations={}#保存貨架位置的字典:loc_id:loc_name_items=[]#保存商品庫存的列表,元素為元組(sku_id,loc_id)definit():"""從磁盤JSON格式文件中讀取數(shù)據(jù)"""global_products,_locations,_itemsifos.path.exists("products.json"):f=open("products.json","r",encoding='utf-8')_products=json.loads(f.read())f.close()數(shù)據(jù)處理模塊data.py的實現(xiàn)(1)通過Python標準庫模塊json中的loads()函數(shù)和dumps()函數(shù),可以實現(xiàn)從JSON文件讀取數(shù)據(jù)和轉(zhuǎn)儲數(shù)據(jù)到JSON文件的功能?!纠?0.16】庫存管理系統(tǒng)數(shù)據(jù)處理模塊data.pyifos.path.exists("locations.json"):f=open("locations.json","r",encoding='utf-8')_locations=json.loads(f.read())f.close()ifos.path.exists("items.json"):f=open("items.json","r",encoding='utf-8')_items=json.loads(f.read())f.close()def_save_products():"""把產(chǎn)品信息數(shù)據(jù)_products以JSON格式保存到磁盤文件"""global_productsf=open("products.json","w",encoding='utf-8')f.write(json.dumps(_products,ensure_ascii=False))f.close()def_save_locations():"""把貨架位置數(shù)據(jù)_locations以JSON格式保存到磁盤文件"""global_locationsf=open("locations.json","w",encoding='utf-8')f.write(json

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論