python項目練習(xí)一:即時標(biāo)記
這是《python基礎(chǔ)教程》后面的實踐,照著寫寫,一方面是來熟悉python的代碼方式,另一方面是練習(xí)使用python中的基本的以及非基本的語法,做到熟能生巧。
這個項目一開始比較簡單,不過重構(gòu)之后就有些復(fù)雜了,但是更靈活了。
按照書上所說,重構(gòu)之后的程序,分為四個模塊:處理程序模塊,過濾器模塊,規(guī)則(其實應(yīng)該是處理規(guī)則),語法分析器。
先來說處理程序模塊,這個模塊的作用有兩個,一個是提供那些固定的html標(biāo)記的輸出(每一個標(biāo)記都有start和end),另一個是對這個標(biāo)記輸出的開始和結(jié)束提供了一個友好的訪問接口。來看下程序handlers.py:
這個程序堪稱是整個“項目”的基石所在:提供了標(biāo)簽的輸出,以及字符串的替換。理解起來也比較簡單。
再來看第二個模塊“過濾器”,這個模塊更為簡單,其實就是一個正則表達(dá)式的字符串。相關(guān)代碼如下:
這就是三個過濾器了,分別是:強調(diào)牌過濾器(用×號標(biāo)出的),url牌過濾器,email牌過濾器。熟悉正則表達(dá)式的同學(xué)理解起來是沒有壓力的。
再來看第三個模塊“規(guī)則”,這個模塊,拋開那祖父類不說,其他類應(yīng)該有的兩個方法是condition和action,前者是用來判斷讀進(jìn)來的字符串是不是符合自家規(guī)則,后者是用來執(zhí)行操作的,所謂的執(zhí)行操作就是指調(diào)用“處理程序模塊”,輸出前標(biāo)簽、內(nèi)容、后標(biāo)簽。 來看下這個模塊的代碼,其實這個里面幾個類的關(guān)系,畫到類圖里面看會比較清晰。 rules.py:
補充utils.py:
最后隆重的來看下“語法分析器模塊”,這個模塊的作用其實就是協(xié)調(diào)讀入的文本和其他模塊的關(guān)系。在往重點說就是,提供了兩個存放“規(guī)則”和“過濾器”的列表,這么做的好處就是使得整個程序的靈活性得到了極大的提高,使得規(guī)則和過濾器變成的熱插拔的方式,當(dāng)然這個也歸功于前面在寫規(guī)則和過濾器時每一種類型的規(guī)則(過濾器)都單獨的寫成了一個類,而不是用if..else來區(qū)分。 看代碼:
這個模塊里面的處理思路是,遍歷客戶端(也就是程序執(zhí)行的入口)給插進(jìn)去的所有的規(guī)則和過濾器,來處理讀進(jìn)來的文本。
有一個細(xì)節(jié)的地方也要說一下,其實是和前面寫的呼應(yīng)一下,就是在遍歷規(guī)則的時候通過調(diào)用condition這個東西來判斷是否符合當(dāng)前規(guī)則。
我覺得這個程序很像是命令行模式,有空可以復(fù)習(xí)一下該模式,以保持記憶網(wǎng)節(jié)點的牢固性。
最后說一下我以為的這個程序的用途, 1、用來做代碼高亮分析,如果改寫成js版的話,可以做一個在線代碼編輯器。 2、可以用來學(xué)習(xí),供我寫博文用。
還有其他的思路,可以留下您的真知灼見。
補充一個類圖,很簡陋,但是應(yīng)該能說明之間的關(guān)系。另外我還是建議如果看代碼捋不清關(guān)系最好自己畫圖,自己畫圖才能熟悉整個結(jié)構(gòu)。
python項目練習(xí)二:畫幅好畫
這是《python基礎(chǔ)教程》中的第二個項目,關(guān)于python操作PDF
涉及到的知識點
1、urllib的使用
2、reportlab庫的使用
這個例子著實很簡單,不過我發(fā)現(xiàn)在python里面可以直接在數(shù)組[]里面寫for循環(huán),真是越用越方便。
下面是代碼:
python項目練習(xí)三:萬能的XML
這個項目的名稱與其叫做萬能的XML不如叫做自動構(gòu)建網(wǎng)站,根據(jù)一份XML文件,生成對應(yīng)目錄結(jié)構(gòu)的網(wǎng)站,不過只有html還是太過于簡單了,如果要是可以連帶生成css那就比較強大了。這個有待后續(xù)研發(fā),先來研究下怎么html網(wǎng)站結(jié)構(gòu)。 既然是通過XML結(jié)構(gòu)生成網(wǎng)站,那所有的事情都應(yīng)該由這個XML文件來。先來看下這個XML文件,website.xml:
有了這個文件,下面應(yīng)該來看怎么通過這個文件生成網(wǎng)站。
首先我們要解析這個xml文件,python解析xml和在java中一樣,有兩種方式,SAX和DOM,兩種處理方式不同點在于速度和范圍,前者講究的是效率,每次只處理文檔的一小部分,快速而能有效的利用內(nèi)存,后者是相反的處理方式,先把所有的文檔載入到內(nèi)存,然后再進(jìn)行處理,速度比較慢,也比較消耗內(nèi)存,唯一的好處就是可以操作整個文檔。
有了上面的這些認(rèn)識,我們已經(jīng)知道如何處理xml文件了,然后再來看那個罪惡的源頭website.xml文件,分析其結(jié)構(gòu),只有兩個節(jié)點:page和directory,很明顯page表示一個頁面,directory表示一個目錄。
所以處理這個xml文件的思路就變的清晰了。讀取xml文件的每一個節(jié)點,然后判斷是page還是directory如果是page則創(chuàng)建html頁面,然后把節(jié)點中的內(nèi)容寫到文件里。如果遇到directory就創(chuàng)建一個文件夾,然后再處理其內(nèi)部的page節(jié)點(如果存在的話)。
下面來看這部分代碼,書中的實現(xiàn)比較復(fù)雜,比較靈活。先來看,然后在分析。
看起來這個程序上面分析的復(fù)雜了一些,不過偉人毛毛說過,任何復(fù)雜的程序都是紙老虎。那我們再來分析一下這個程序。
首先看到這個程序是有兩個類,其實完全可以當(dāng)作一個類,因為有了繼承。
然后再來看它多了些什么,除了我們分析出來的startElement和endElement以及characters,多出來了startPage,endPage;startDirectory,endDirectory;defaultStart,defaultEnd;ensureDirectory;writeHeader,writeFooter;和dispatch,這些個函數(shù)。除了dispatch,前面的函數(shù)都很好理解,每一對函數(shù)都是單純的處理對應(yīng)的html標(biāo)簽以及xml節(jié)點。而dispatch比較復(fù)雜,復(fù)雜之處在于他是用來動態(tài)拼合函數(shù)并且進(jìn)行執(zhí)行的。
dispatch的處理思路是,首先根據(jù)傳遞的參數(shù)(就是操作名稱以及節(jié)點名稱)判斷是否存在對應(yīng)的函數(shù)如startPage,如果不存在則執(zhí)行default+操作名稱:如defaultStart。
一個函數(shù)一個函數(shù)搞清楚之后,就知道整個處理流程是什么樣了。首先創(chuàng)建一個public_html的文件,存放整個網(wǎng)站,然后讀xml的節(jié)點,通過startElement和endElement調(diào)用dispatch進(jìn)行處理。然后就是dispatch怎么調(diào)用具體的處理函數(shù)了。 到此為止,這個項目算是分析完了。
主要掌握的內(nèi)容一個是python中使用SAX處理XML,另一個就是python中的函數(shù)的使用,比如getattr,傳參數(shù)時的星號……
python項目練習(xí)四:新聞聚合
書中的第四個練習(xí),新聞聚合。現(xiàn)在很少見的一類應(yīng)用,至少我從來沒有用過,又叫做Usenet。這個程序的主要功能是用來從指定的來源(這里是Usenet新聞組)收集信息,然后講這些信息保存到指定的目的文件中(這里使用了兩種形式:純文本和html文件)。這個程序的用處有些類似于現(xiàn)在的博客訂閱工具或者叫RSS訂閱器。
先上代碼,然后再來逐一分析:
這個程序,首先從整體上進(jìn)行分析,重點部分在于NewsAgent,它的作用是存儲新聞來源,存儲目標(biāo)地址,然后在分別調(diào)用來源服務(wù)器(NNTPSource以及SimpleWebSource)以及寫新聞的類(PlainDestination和HTMLDestination)。所以從這里也看的出,NNTPSource是專門用來獲取新聞服務(wù)器上的信息的,SimpleWebSource是獲取一個url上的數(shù)據(jù)的。而PlainDestination和HTMLDestination的作用很明顯,前者是用來輸出獲取到的內(nèi)容到終端的,后者是寫數(shù)據(jù)到html文件中的。
有了這些分析,然后在來看主程序中的內(nèi)容,主程序就是來給NewsAgent添加信息源和輸出目的地址的。
這確實是個簡單的程序,不過這個程序可是用到了分層了。
python項目練習(xí)五:虛擬茶話會
幾乎在學(xué)習(xí)、使用任何一種編程語言的時候,關(guān)于socket的練習(xí)從來都不會少,尤其是會寫一些局域網(wǎng)的通信的東西。所以書上的這個項目剛好可以練習(xí)一下socket編程。
這個練習(xí)的整體思路首先有一個聊天的服務(wù)器,這個服務(wù)器的功能主要是提供客戶端socket的連接、存儲每個客戶端的連接session,處理每個連接發(fā)送的消息、解析客戶端發(fā)送的數(shù)據(jù)。就這些,至于客戶端方面不需要寫代碼,用系統(tǒng)的telnet工具即可。
我覺得有了上面的分析,剩下的這個程序就沒有什么說的了,當(dāng)然,除了那兩個把socket封裝的類之外。
自己使用python中的socket類嘗試這個編寫了一個簡單的通信程序,不過不知為什么,通信中總是出現(xiàn)意外。這段簡單的代碼如下:
server.py
clinet.py
這個程序出錯的原因沒有去細(xì)揪,因為python中提供了兩個封裝好的類來完成socket通信過程:asynchat中的async_chat和asyncore中的dispatcher以及asyncore本身。前面的類是用來處理客戶端同服務(wù)器的每一次會話,后面的類主要是用來提供socket連接服務(wù)。并且將每一個socket連接都托管給前者(async_chat)來處理。
來看代碼:
整個程序分為我一開始說的三個部分:
提供客戶端的socket連接:ChatServer類。
存儲每個客戶端的連接session,處理每個連接發(fā)送的消息:ChatSession類,這個類的作用很簡單,接受數(shù)據(jù),判斷是否有終結(jié)符,如果有調(diào)用found_terminator這個方法。
解析客戶端發(fā)送的數(shù)據(jù):就是剩下的room相關(guān)的類,這些類分別用來處理客戶端發(fā)送的字符串和命令,都是繼承自CommandHandler。
最終截圖:
python項目練習(xí)六:使用CGI進(jìn)行遠(yuǎn)程編輯
記得一開始接觸web開發(fā)的時候,看視頻,視頻里面的老師一般都會語重心長的說:想當(dāng)年我們一開始學(xué)習(xí)編程那會兒,都是用cgi編程,復(fù)雜的很,現(xiàn)在你們學(xué)習(xí)web編程,直接有現(xiàn)成的框架來用,十分簡單。記得當(dāng)然聽完這句話之后就會覺得這個老師好有經(jīng)驗,技術(shù)很高。
不過后來慢慢的接觸web編程時間長了,覺得cgi編程并不是像傳說中的那么難,只不過是比較麻煩,在后臺使用html硬編碼來完成(也就是在后臺使用類似print的語句輸出html)。通過瀏覽器直接訪問cgi文件,由web服務(wù)器執(zhí)行cgi腳本,輸出內(nèi)容到瀏覽器。關(guān)于cgi的更多內(nèi)容可以參考這里:http://www.jdon.com/idea/cgi.htm
再來看這個python中的cgi,確實很簡單。但是有一點我不確定,就是如果我是初學(xué)web編程的話,會不會覺得這個簡單,這個角度的思考確實不好操作。
下面直接上代碼吧,和書上的不太一樣,因為書上的代碼在我的電腦上不能正常運行。 首先是index.html:
edit.cgi,用來接受index頁面的名字,然后根據(jù)名字查找文件,并且輸出。
最后一個文件save.cgi:
代碼理解上比較簡單,唯一麻煩的地方是web服務(wù)器的配置。 我這里使用的是tomcat來做web服務(wù)器。需要修改tomcat配置,首先是配置cgi,我引用一段從網(wǎng)上搜來的文字:
要為Tomcat配置CGI服務(wù)主要有下面幾個步驟:
把servlets-cgi.renametojar (在%CATALINA_HOME%/server/lib/目錄下)改名為servlets-cgi.jar。
在Tomcat的%CATALINA_BASE%/conf/web.xml 文件中,把關(guān)于 CGI的那段的注釋去掉。內(nèi)容樣式如下:
其中參數(shù)executable需要自已添加進(jìn)去,它的值就是我們用來解釋CGI腳本的程序。一般情況下這里會配置為Perl。"C:/Perl/bin/"為Perl的安裝目錄。
在Tomcat的%CATALINA_BASE%/conf/web.xml文件中,把關(guān)于對CGI進(jìn)行映射的那段的注釋去掉。內(nèi)容樣式如下:
其中url-pattern就是將來我們訪問CGI腳本的url地址模式。
完成上面三個步驟后,我們的Tomcat服務(wù)器就具有了運行CGI腳本的能力了。
摘自:http://www.blogjava.net/Tauruser/archive/2007/09/06/143097.html
使用hello.cgi測試一下:
然后測試能運行的話,就要把代碼放到tomcat的webapp下的某一個app下的WEB-INF中的cgi下。,比如我這里的cgi文件是在tomcat/webapps/test/WEB-INF/cgi/下。另外在cgi目錄下要建立一個data文件夾,里面放一個test.txt文件。
最后執(zhí)行效果如圖:
python項目練習(xí)七:自定義公告板
這依然是一個cgi的項目,有了前面的一個項目作為基礎(chǔ),這個里面沒有什么難點。不過,和書上不同的是,我這里使用的數(shù)據(jù)庫是mysql,所以有興趣的童鞋,可以參考一下。
首先建立一張mysql的數(shù)據(jù)表:
然后你要確定你的系統(tǒng)中已經(jīng)安裝了連接mysql的python模塊,怎么確定呢。命令行下,進(jìn)入python,然后輸入import MySQLdb,注意大小寫,如果沒有報錯,說明安裝了,如果報錯,從網(wǎng)上找python連mysql的方法,很多。
準(zhǔn)備就緒,開始分析整個程序吧。
一個很簡單的電子公告版,主要功能有,展示所有公告,查看單個公告,編輯公告,保存公告。所以根據(jù)功能建立四個文件:main.py,view.py,edit.py,save.py,每個文件,負(fù)責(zé)一個模塊。
下面就上代碼吧,太簡單了。 main.py:
view.py
edit.py
save.py
python項目練習(xí)八:使用XML-RPC進(jìn)行遠(yuǎn)程文件共享
這是個不錯的練習(xí),使用python開發(fā)P2P程序,或許通過這個我們可以自己搞出來一個P2P下載工具,類似于迅雷。說到迅雷,關(guān)于其原理不知道大家是否了解,如果你不了解,我想看完這篇文章,你一定會了解的。啥,你已經(jīng)了解了?那就過來指點一番。
以前在java中也接觸過類似的概念。一個是RMI( Remote Method Invocation)的概念,另外一個就是XML-RPC的概念。
那么什么是XML-RPC呢?它和P2P有什么關(guān)系?下面談?wù)勎业膫€人理解。
XML-RPC是一個遠(yuǎn)程過程調(diào)用(remote procedure call,RPC)的分布式計算協(xié)議,通過XML將調(diào)用函數(shù)封裝,并使用HTTP協(xié)議作為傳送機制[摘自維基百科]。所以這個XML-RPC可以幫助我們完成遠(yuǎn)程調(diào)用的工作,即調(diào)用相鄰電腦中的方法,當(dāng)然前提是在相鄰電腦中已經(jīng)有我們編寫的供遠(yuǎn)程調(diào)用的程序在運行(不管是在前臺還是后臺,就像迅雷一樣,總是悄悄運行)。
這里還要提出來一個概念:Node,即節(jié)點。每一個電腦被為一個節(jié)點,這個只是針對每個電腦只運行一個我們通過XML-RPC編寫的程序,如果電腦中同時運行了多個程序,其實每一個程序都是一個節(jié)點。有了節(jié)點這樣的一個概念之后,我想大家可以想象的出來了,不同節(jié)點之間相連,形成各種復(fù)雜的網(wǎng)狀結(jié)構(gòu)。
這時每個節(jié)點可以和其他多個節(jié)點進(jìn)行相連,但是我們沒必要讓一個節(jié)點通其他所有的節(jié)點都相連,鏈接太多會很亂,就像人際關(guān)系一樣。那什么時候連哪些節(jié)點呢?這時就要說到P2P了,所謂P2P即指peer to peer,也就是點到點。說是點到點,你可千萬別認(rèn)為只是從一點到一點,因為他可能是從多點到一點,或者一點到多點。而沒有固定的從哪個點到哪個點,所有的點都可以相連。
因此在下載東西方面,這樣的協(xié)議就比傳統(tǒng)的只是從某一點下載數(shù)據(jù)要快很多,資源也會多很多。
其運作流程是這樣的,我打一個比方:比如小A在迅雷里下載B片,迅雷上面可以沒有這個資源,但是他可以幫你從節(jié)點中找,看誰又這個資源,剛好小C電腦里有,并且在迅雷共享目錄下,然后迅雷就會把小C電腦中把資源通過自己的節(jié)點傳回到小A的電腦上,當(dāng)然更可能的情況是直接讓小A和小C相連。
大家在使用迅雷下載東西的時候肯定注意過里面有一項資源:x/xx這樣的東西,我覺得,前面的那個x的意思表示當(dāng)為你提供資源的節(jié)點數(shù)量,后面的那個xx表示,所有擁有該資源的節(jié)點數(shù)目,這些節(jié)點可能并不在線。
理解了基本的概念之后,再來看python中如何來實現(xiàn)。
可以先做一個小小的嘗試: 首先進(jìn)入命令行,輸入python,然后輸入一下代碼:
然后在啟動一個命令行,進(jìn)入pyhon。 輸入:
from xmlrpclib import ServerProxy s = ServerProxy('http://localhost:4242') s.twice(2) #通過ServerProxy調(diào)用遠(yuǎn)程的方法,
然后你就會看到通過遠(yuǎn)程方法的計算完成。
是不是很輕松,這個還是比較簡陋,不過足以讓你理解python的遠(yuǎn)程調(diào)用,再來看看完整的吧。
先上代碼,然后再詳解。 首先是Server.py:
首先來看上面的幾個常量設(shè)置: SimpleXMLRPCServer.allow_reuse_address表示,其所占用的端口可以重用,即如果你強制關(guān)閉node server之后再次重啟,不會出現(xiàn)端口被占用的情況。
MAX_HISTORY_LENGTH = 6 這個是設(shè)置最大的節(jié)點長度,因為不能讓讓節(jié)點無休止的搜索下去。
UNHANDLED = 100 ACCESS_DENIED = 200 這倆就是返回碼。
然后再來看個node節(jié)點的具體流程。 這個段代碼的流程這這樣的,首先,啟動供遠(yuǎn)程調(diào)用的服務(wù)器,調(diào)用的接口就是Node類。在Node類中有三個方法供遠(yuǎn)程調(diào)用的,一個是hello,一個是fetch還有一個query。hello 這個方法就是添加鄰節(jié)點信息到當(dāng)前節(jié)點中。而fetch則是用來獲取數(shù)據(jù)的方法,query是節(jié)點之間用來交互的。
在fetch方法中,首先判斷密碼是否正確,然后通過調(diào)用自己的query方法查找數(shù)據(jù)。我們來看query方法,這個方法中,先是調(diào)用私有方法_handle本地查找,如果沒找到,那么在通過_broadcast接口在所有已知節(jié)點中發(fā)送廣播,這里要注意histroy,每次廣播都會傳遞history這個參數(shù),這個參數(shù)的作用有二:一是、防止往重復(fù)的節(jié)點中發(fā)送廣播;二是、限制當(dāng)前所有鏈接節(jié)點的長度。
理解了一個node server的基礎(chǔ)功能之后,再來看對server進(jìn)行管理的控制類代碼。
client.py:
來分析一下這段代碼,前面的參數(shù)就不看了,很好理解,一開始有一個隨機生成密碼的函數(shù),做什么用的呢?主要是用來防止別人非法調(diào)用該控制所控制的node server的。這密碼 我們也不用記,因為我們有client的合法使用權(quán)。呵呵。
這段代碼的總體作用就是為你提供一個可視的命令行的界面,通過繼承cmd這個類,來解析你輸入的命令,比如程序運行之后,出現(xiàn)命令提示符,你輸入fetch,那么它會調(diào)用到do_fetch這個方法中來,并把參數(shù)傳遞進(jìn)來。
do_fetch這個方法的所用就是調(diào)用node server中的fetch方法,獲取資源。
另外的一個do_exit很好理解,就是接受exit命令退出程序。
在程序初始化的時候,還有一點需要注意,就是它會讀取你urlfile參數(shù)傳遞的文件中的數(shù)據(jù),這個里面放的是節(jié)點的url地址。讀取之后程序會把這些地址加到相鄰節(jié)點中,供以后訪問。不過這個程序還有些不完善的地方就是在程序運行時,如果你修改了url配置的文件,他不會讀取你新添加的節(jié)點url。不過這個修改很簡單,把獲取url的代碼放到do_fetch中就行了。
在運行程序之前還有一些工作要做。 首先需要建立兩個文件夾,A和C,C文件夾里面創(chuàng)建一個文件,B.txt,在A和C所在文件夾中建立urlsA.txt和urlsC.txt文件。里面在urlsA.txt中寫入:http://localhost:4243,然后開啟兩個命令行,
第一個輸入:python client.py urlsA.txt Ahttp://localhost:4242回車,是不是出來提示符了。輸入fetch B.txt回車,看到提示Couldn't find the file B.txt。
然后在第二個命令行中輸入python client.py urlsC.txt Chttp://localhost:4243回車。同樣輸入fetch B.txt回車,是不是沒反應(yīng)。說明該文件存在。接在在第一個命令行中再次輸入fetch B.txt看,是否還是提示沒找到文件,如果你對代碼根據(jù)我上面的建議進(jìn)行了修改的話,就不會出現(xiàn)錯誤了,如果沒有修改,此時你需要把輸入exit退出程序,再次重啟,然后在fetch B.txt,然后到A文件夾下查看一下,看是不是把B.txt下載到你的文件夾中了。
PS:上面的程序只能傳輸文本文件,大文件或者其他格式的文件無法傳輸,剛才研究了一下,使用xmlrpclib這個庫中的Binary函數(shù)即可,具體使用訪問為: 先引入xmlrpclib,import xmlrpclib 在server類的的_handle方法中最后返回的那句代碼return open(name).read() 修改為 return xmlrpclib.Binary(open(name,'rb').read()) 再把fetch方法中的f.write(result)修改為f.write(result.data) 另外這句話前面的那個寫文件的方式要改為wb。
python項目練習(xí)九:文件共享2-GUI版本
有了前面的P2P基礎(chǔ),這一個練習(xí)就是給程序加一個可視化的界面,俗稱GUI。
python里面的界面庫有很多,如wxPython、wgGTK、tkinter,還有QT,按照書中的實例,我也使用wxPython來做界面。話說有了這個界面之后,我發(fā)現(xiàn)迅雷的網(wǎng)鄰也不過如此(稍有夸張的成份),不過這個項目的練習(xí)之上再繼續(xù)擴(kuò)展的話,基本效果可以達(dá)到網(wǎng)鄰的那種,如果有時間的話我可以繼續(xù)擴(kuò)展這個項目。下面就開始編寫GUI。
這個里面的主要的問題應(yīng)該都集中在界面上,遠(yuǎn)程共享的代碼已經(jīng)不需要修改了,只需要把現(xiàn)在的界面接上前面的代碼就ok。這個wxPython庫的使用,我覺得和以前使用java的awt編寫界面沒啥區(qū)別,沒有什么難點,只是需要理解里面的幾個概念,像是按鈕、文本框、綁定事件,僅此而已。
還是來看代碼吧:
這個相比于前面關(guān)于xml-rpc的實現(xiàn)就簡單的多了。
關(guān)于擴(kuò)展的思路,目前我的想法是這樣的,現(xiàn)在的程序監(jiān)聽的端口是通過命令行參數(shù)決定的。我覺得可以直接寫到窗口上輸入或者寫死在程序里,畢竟是要使用固定的端口通信的,還有共享的文件夾以及urls里面的節(jié)點,都可以是固定的。
另外可以添局域網(wǎng)查詢功能,就像是現(xiàn)在迅雷網(wǎng)鄰的換一換,就是查找當(dāng)前局域網(wǎng)內(nèi)正在使用我們軟件的所有用戶,然后把他們的資源情況列到我們的列表上。
python項目練習(xí)十:DIY街機游戲
終于來到了最后一個項目,看看前面的那些練習(xí),也算是熟悉了python的基本操作,也知道python能干哪些事情,最后一個項目相比于以前的稍微復(fù)雜些,但是任何一個程序只要他是可以正常執(zhí)行的,花點時間總會搞明白的。
這個練習(xí)是一個小游戲程序,如果要是給它起個名字的話,應(yīng)該叫:快躲,香蕉。主要的游戲內(nèi)容就是,游戲開始會從屏幕上方不斷隨便的掉一些鐵塊,在屏幕下方有一個小香蕉是受你控制的,你需要不斷的左右移動來躲避鐵塊。在你躲避完一定數(shù)量的鐵塊之后,就會進(jìn)入下一關(guān)。下一關(guān)依然是讓你躲鐵塊,不過鐵塊下降的速度就快了很多。在游戲中你可以按下任意鍵暫停,再次按則繼續(xù),按下ESC鍵退出。這就是全部的功能了,下面我們來看游戲的實現(xiàn)。
無論是在實現(xiàn)功能時還是在代碼分析的時候,分類歸納總是一個好習(xí)慣,這里自然也不例外。
首先對所有代碼分類, 1、整體上代碼有一個配置模塊,來對游戲的速度、屏幕的寬度、香蕉移動速度、字體大小、各個物體的圖片等進(jìn)行配置。 2、然后是有一個元素模塊,即游戲中的兩個元素落下來的鐵塊以及被砸的香蕉,其中還要包含他們具有的行為。 3、然后還有游戲中的各種狀態(tài)模塊,狀態(tài)模塊中的類繼承關(guān)系稍微多一些,處于家譜最上方的就是state類,由它來衍生其他的所有狀態(tài),它的直接子類是Level和Pause,其中Pause有衍生出子類Info、levelCleared、GameOver、StartUp。 4、最后就是游戲的主模塊,用來讓其他模塊協(xié)調(diào)工作的。
然后再來看一個整體圖:
有了上面整體的認(rèn)識,下面就要細(xì)揪一下了。我自己看代碼的方法是這樣的,首先整體分析,然后在從程序的入口點開始分析。我估計大多數(shù)人也是這么做的。
首先是squish.py文件中的game類:
忽略掉init中的設(shè)置代碼,在run中,該管理類首先調(diào)用pygame初始化并啟動游戲界面,然后在一個while True的死循環(huán)中不斷的進(jìn)行狀態(tài)判斷,事件處理,然后根據(jù)事件更新當(dāng)前狀態(tài),并且繪制界面。
讓我們把焦點放在那個死循環(huán)中,因為他就是整個程序的流程所在。 其中狀態(tài)和事件的關(guān)系就是,當(dāng)發(fā)生某一事件之后,狀態(tài)就會發(fā)生變化,比如點擊事件、過關(guān)事件、死亡事件。這些事件的來源分別是:用戶操作、系統(tǒng)判斷、系統(tǒng)判斷。要繼續(xù)深入分析就需要再拿一部分代碼出來。
依然是來自squish.py文件中剩余的所有代碼:
objects.py中的代碼:
在類Banana和Weight中的update和touches方法,用于進(jìn)行系統(tǒng)判斷。
好了,到這主要的東西都分析完了,剩下的只需要稍看一下就能夠懂得了。
最后還有一個配置模塊的代碼config.py:
到此為止,《python基礎(chǔ)教程》中的十個項目都已經(jīng)分析了一遍,下一步要做的就是做幾個實用軟件出來,然后把python再好好深入研究下。
應(yīng)曉勇要求,上幾個運行圖:
作者:the5fire
轉(zhuǎn)載出處:https://www.the5fire.com/
喜歡記得來一個