通過之前的學習我們已經了解了Python的很多基礎運用了,現在我們嘗試着做一個有使用價值的小腳本。
問題
需求:
我想要一個可以給我備份重要文件的程序。
需求分析:
首先文件是有存儲路徑,文件的路徑和備份的路徑,是一個文件還是很多文件,備份成什么樣子的文件?
簡單的分析過后,大概制定實現步驟:
1.需要備份的文件和目錄由一個列表指定。
2.備份應該保存在主備份目錄下。
3.文件備份成一個zip文件。
4.zip存檔的名稱是當前的日期和時間。
解決方案
當我們完成基本的程序設計的時候,就可以編寫我們的代碼了,這就是需求的實現過程。
版本一
import os import time #1.帶備份文件路徑或者完整地址加文件名 source = ['E:\python\\']#\\被轉義 #2.文件備份地址 target_dir = 'E:\\backup\\' #3.備份后的文件路徑加文件名 target = target_dir + time.strftime('%Y%m%d%H%M%S') + '.rar' #4.使用zip命令壓縮文件zip命令有一些選項和參數。-q選項用來表示zip命令安靜地工作。-r選項表示zip命令對目錄遞歸地工作,即它包括子目錄以及子目錄中的文件。 zip_command = "zip -qr {0} {1}".format(target, ''.join(source)) #5.通過給系統傳遞參數來執行壓縮命令(壓縮使用的是WinRAR所帶文件rar.exe來執行壓縮) if os.system(zip_command) == 0:#如果命令成功運行,它返回0,否則它返回錯誤號。 print ('Successful backup to', target) else: print ('Backup FAILED')
運行結果
當然程序是可以不斷優化的,沒有最優只有更優。
測試
現在我們做的就是程序的測試,在這個階段首先查看程序是否能正常運行,其次是查看運行結果是否與需求一致,如果和我們的預期結果不一致,我們就要調試我們的程序,從而消除“bug”。
工作原理
我們使用了os和time模塊,所以我們引用他們import。之后我們在source列表中指定需要備份的文件和目錄。目標目錄是我們想要存儲備份文件的地方,它由target_dir變量指定。zip歸檔的名稱是目前的日期和時間(可改的),我們使用time.strftime()函數獲得。它還包括.zip擴展名,將被保存在target_dir目錄中。
time.strftime()函數需要我們在上面的程序中使用的那種制定。%Y會被無世紀的年份所替代。%m會被01~12之間的一個是十進制月份數替代,其他以此類推。
我們使用加法操作符來連接字符串,把兩個字符串連接在一起返回一個新的字符串。通過這個方式我們創建目標文件的名稱。接着我們創建zip_command字符串,它包含我們將要執行的命令。你可以在DOS中運行它,檢驗是否正確。
zip命令有一些選項和參數。-q
選項用來表示zip命令安靜地工作。-r
選項表示zip命令對目錄遞歸地工作,即它包括子目錄以及子目錄中的文件。兩個選項可以組合成縮寫形式-qr
。選項后面跟着待創建的zip歸檔的名稱,然后再是待備份的文件和目錄列表。我們使用已經學習過的字符串join
方法把source
列表轉換為字符串。{0}表示target,{1}表示''.join(source)。
最后,我們使用os.system
函數 運行 命令,利用這個函數就好像在 系統 中運行命令一樣。即在shell中運行命令——如果命令成功運行,它返回0,否則它返回錯誤號。根據命令的輸出,我們打印對應的消息,顯示備份是否創建成功。
版本二
第一個腳本已經可以工作了,然而我們還可以對他進行優化,使它更強大。
優化之一是采用更好的文件名機制——使用 時間 作為文件名,而當前的 日期 作為目錄名,存放在主備份目錄中。這樣做的一個優勢是你的備份會以等級結構存儲,因此它就更加容易管理了。另外一個優勢是文件名的長度也可以變短。還有一個優勢是采用各自獨立的文件夾可以幫助你方便地檢驗你是否在每一天創建了備份,因為只有在你創建了備份,才會出現那天的目錄。
import os import time #1.帶備份文件路徑或者完整地址加文件名 source = ['E:\python\\'] #2.文件備份地址 target_dir = 'E:\\backup\\' #3.使用日期創建一個文件路徑 today = target_dir + time.strftime('%Y%m%d') now = time.strftime('%H%M%S') #4.判斷這個路徑是否存在,不存在新建路徑 if not os.path.exists(today): os.mkdir(tody) print('Successfully created directory',tody) #5.備份后的文件路徑加文件名os.sep = \\ target = today + os.sep + now + '.zip' #5.使用zip命令壓縮文件zip命令有一些選項和參數。-q選項用來表示zip命令安靜地工作。-r選項表示zip命令對目錄遞歸地工作,即它包括子目錄以及子目錄中的文件。 zip_command = "zip -qr {0} {1}".format(target, ''.join(source)) #6.通過給系統傳遞參數來執行壓縮命令(壓縮使用的是WinRAR所帶文件rar.exe來執行壓縮) if os.system(zip_command) == 0: print ('Successful backup to', target) else: print ('Backup FAILED')
運行結果
兩個程序的大部分是相同的。改變的部分主要是使用os.exists
函數檢驗在主備份目錄中是否有以當前日期作為名稱的目錄。如果沒有,我們使用os.mkdir
函數創建。
注意os.sep
變量的用法——這會根據你的操作系統給出目錄分隔符,即在Linux、Unix下它是'/'
,在Windows下它是'\\'
,而在Mac OS下它是':'
。使用os.sep
而非直接使用字符,會使我們的程序具有移植性,可以在上述這些系統下工作。
版本三
import os import time #1.帶備份文件路徑或者完整地址加文件名 source = ['E:\python\\'] #2.文件備份地址 target_dir = 'E:\\backup\\' #3.使用日期創建一個文件路徑 today = target_dir + time.strftime('%Y%m%d') now = time.strftime('%H%M%S') #4.從用戶處獲取注釋以創建zip文件的名稱 comment = input('Enter a comment --> ') if len(comment) == 0: # 檢查用戶輸入 target = today + os.sep + now + '.zip' else: target = today + os.sep + now + '_' + \ comment.replace(' ', '_') + '.zip' #5.判斷這個路徑是否存在,不存在新建路徑 if not os.path.exists(today): os.mkdir(today) print('Successfully created directory',tody) #6.使用zip命令壓縮文件zip命令有一些選項和參數。-q選項用來表示zip命令安靜地工作。-r選項表示zip命令對目錄遞歸地工作,即它包括子目錄以及子目錄中的文件。 zip_command = "zip -qr {0} {1}".format(target, ''.join(source)) #7.通過給系統傳遞參數來執行壓縮命令(壓縮使用的是WinRAR所帶文件rar.exe來執行壓縮) if os.system(zip_command) == 0: print ('Successful backup to', target) else: print ('Backup FAILED')
運行結果
如何工作
這個程序現在工作了!讓我們看一下版本三中作出的實質性改進。我們使用input
函數得到用戶的注釋,然后通過len
函數找出輸入的長度以檢驗用戶是否確實輸入了什么東西。如果用戶只是按了回車(比如這只是一個慣例備份,沒有做什么特別的修改),那么我們就如之前那樣繼續操作。
然而,如果提供了注釋,那么它會被附加到zip歸檔名,就在.zip
擴展名之前。注意我們把注釋中的空格替換成下划線——這是因為處理這樣的文件名要容易得多。
進一步優化
另一個可能的改進是使文件和目錄能夠通過命令行直接傳遞給腳本。我們可以通過sys.argv
列表來獲取它們,然后我們可以使用list
類提供的extend
方法把它們加到source
列表中去。
我還希望有的一個優化是使用tar命令替代zip命令。這樣做的一個優勢是在你結合使用tar和gzip命令的時候,備份會更快更小。如果你想要在Windows中使用這些歸檔,WinZip也能方便地處理這些.tar.gz
文件。tar命令在大多數Linux/Unix系統中都是默認可用的。
軟件的開發過程
現在,我們已經走過了編寫一個軟件的各個環節。這些環節可以概括如下:
- 什么(分析)
- 如何(設計)
- 編寫(實施)
- 測試(測試與調試)
- 使用(實施或開發)
- 維護(優化)
重要
我們創建這個備份腳本的過程是編寫程序的推薦方法——進行分析與設計。開始時實施一個簡單的版本。對它進行測試與調試。使用它以確信它如預期那樣地工作。再增加任何你想要的特性,根據需要一次次重復這個編寫-測試-使用的周期。記住“軟件是長出來的,而不是建造的”。