您好,登錄后才能下訂單哦!
最近在用Python寫一個一鍵替換文件的腳本文件,大概的功能是,向程序傳遞一個本地或SFTP目錄的參數(shù),程序可以把指定目錄所有文件替換到特定應用程序的對應目錄。程序提供了如下2種命令行調(diào)用:
Usage: demo.py [sourcedir]
Usage: demo.py [sourcedir] bydir
第一種調(diào)用的實際操作是:讀取特定應用程序目錄所有文件,并獲取全路徑作為一個集合,再把參數(shù)文件夾中文件按文件名與集合中文件進行匹配,如果匹配上則執(zhí)行替換操作。
第二種調(diào)用的實際操作是:按參數(shù)文件夾的目錄存放的路徑,完整替換到應用程序的對應目錄。
下面是最初的代碼實現(xiàn):
#執(zhí)行本地文件替換的具體操作
def ReplaceLocalFiles(filepath, context, filecontext, softpath, bydir):
if (":" not in filepath) or (not os.path.isdir(filepath)):
printandwritelog(u"目標路徑有誤,請確認是目錄后再重試")
return "error"
fileList = os.walk(filepath)
for root, dirs, files in fileList:
for file in files:
if bydir:#如果按目錄進行替換的話走下面這個邏輯分支
filefullpath = os.path.join(root, file)
targetfullpath = filefullpath.replace(filepath, softpath)
shutil.copy2(filefullpath, targetfullpath)
printandwritelog(u"文件 %s 拷貝到 %s 成功" % (filefullpath, targetfullpath))
else:#如果自行查找文件路徑進行替換的話先走下這個邏輯分支
filecounts = checkcount(file, filecontext)
if (0 == filecounts):
printandwritelog(u"沒有找到文件%s的路徑,請使用指定路徑方式進行替換" % file)
continue
elif (1 < filecounts):
printandwritelog(u"文件 %s 有 %s 個路徑,請使用指定路徑方式進行替換" % (file , filecounts))
continue
elif (1 == filecounts):
for line in context.split("\n"):
filename = line.split("\\")[-1]
if file == filename:
os.rename(line , line + str(random.randint(0, 100)))
shutil.copy2(os.path.join(root, file), line)
printandwritelog(u"文件 %s 拷貝到 %s 成功" % (os.path.join(root, file), line))
else:
printandwritelog(u"替換文件個數(shù)有誤%s" % file)
#判斷如果是本地文件則直接調(diào)用替換函數(shù),如果是網(wǎng)絡路徑,則先下載文件再替換
def RelpaceFiles(filepath, context, filecontext, softpath, bydir):
if ":" in filepath:
printandwritelog(u"提供的本地路徑,走本地路徑文件替換流程")
ReplaceLocalFiles(filepath, context, filecontext, softpath, bydir)
else:
printandwritelog(u"提供的FTP路徑,先下載文件到本地后再執(zhí)行替換流程")
sourceFileDir = cur_file_dir() + r"\testdir"
if os.path.isdir(sourceFileDir):
shutil.rmtree(sourceFileDir)
obj = netutilex.SFTP("192.168.1.100", "test", "testpwd")
obj.syncSftpDir(filepath, sourceFileDir)
obj.close()
ReplaceLocalFiles(sourceFileDir, context, filecontext, softpath, bydir)
#先處理替換前的前置操作,環(huán)境準備好之后執(zhí)行替換操作
def ReplaceAllFiles(filepath, bydir):
softpath = checkinst()
if ("notinst" == softpath):
printandwritelog(u"沒有檢測到衛(wèi)士安裝目錄,請確認后重試")
return "error"
else:
context, filecontext = getallfiles(softpath)
RelpaceFiles(filepath, context, filecontext, softpath, bydir)
先簡單說明下各函數(shù)的功能:
ReplaceLocalFiles:主要功能函數(shù),實現(xiàn)具體的替換操作;
RelpaceFiles:根據(jù)傳入?yún)?shù)判斷是否是網(wǎng)絡路徑,如果是則先把文件下載到本地,然后調(diào)用ReplaceLocalFiles執(zhí)行替換操作;
ReplaceAllFiles:做了一些環(huán)境準備的事情,然后調(diào)用實際的功能函數(shù)RelpaceFiles進行干活;
printandwritelog:記錄日志并輸出;
checkinst:檢查目標程序是否安裝,如果安裝則返回安裝路徑;
getallfiles:獲取目標應用程序的文件全路徑集合;
checkcount:獲取指定文件名在目標應用程序文件集合中出現(xiàn)的次數(shù)
netutilex:一個獨立的操作SFTP的庫文件。
從目前的代碼中能發(fā)現(xiàn)至少有2個地方可以優(yōu)化:
對于第1點,優(yōu)化的思路是:對于非所有函數(shù)都必須調(diào)用的參數(shù),盡可能的固化到實際使用的函數(shù)中,避免各函數(shù)僅僅做了傳遞員的工作。
對于第2點,優(yōu)化的思路是:合并同類項,對于重復代碼的部分,盡可能提取到共用邏輯中實現(xiàn)。
下面是優(yōu)化后的代碼:
#執(zhí)行本地文件替換的具體操作
def ReplaceLocalFiles(filepath, bydir):
if (":" not in filepath) or (not os.path.isdir(filepath)):
printandwritelog(u"目標路徑有誤,請確認是合法目錄后重試")
return "error"
softpath = checkinst()
if ("notinst" == softpath):
printandwritelog(u"沒有獲取到目標軟件安裝目錄,請確認后重試")
return "error"
context, filecontext = getallfiles(softpath)
fileList = os.walk(filepath)
for root, dirs, files in fileList:
for file in files:
filefullpath = os.path.join(root, file)
targetfullpath = filefullpath.replace(filepath, softpath)
if not bydir:#如果自行查找文件路徑進行替換的話先走下這個邏輯分支
filecounts = checkcount(file, filecontext)
if (0 == filecounts):
printandwritelog(u"沒有找到文件%s的路徑,請使用指定路徑方式進行替換" % file)
continue
elif (1 < filecounts):
printandwritelog(u"文件 %s 有 %s 個路徑,請使用指定路徑方式進行替換" % (file , filecounts))
continue
elif (1 == filecounts):
for line in context.split("\n"):
filename = line.split("\\")[-1]
if file == filename:
targetfullpath = line
else:
printandwritelog(u"替換文件個數(shù)有誤%s" % file)
if os.path.isfile(targetfullpath):
randomend = random.randint(0, 100)
os.rename(targetfullpath , targetfullpath + str(randomend))
shutil.copy2(filefullpath, targetfullpath)
printandwritelog(u"文件 %s 拷貝到 %s 成功" % (filefullpath, targetfullpath))
#先處理替換前的前置操作,環(huán)境準備好之后執(zhí)行替換操作
def ReplaceAllFiles(filepath, bydir):
sourceFileDir = filepath
if ":" in filepath:
printandwritelog(u"提供的本地路徑,走本地路徑文件替換流程")
else:
printandwritelog(u"提供的FTP路徑,先下載文件到本地后再執(zhí)行替換流程")
sourceFileDir = cur_file_dir() + r"\testdir"
if os.path.isdir(sourceFileDir):
shutil.rmtree(sourceFileDir)
obj = netutilex.SFTP("192.168.1.100", "test", "testpwd")
obj.syncSftpDir(filepath, sourceFileDir)
obj.close()
ReplaceLocalFiles(sourceFileDir, bydir)
具體的優(yōu)化操作有:
把函數(shù)checkinst和getallfiles的調(diào)用實現(xiàn)放到了其返回值使用者ReplaceLocalFiles的函數(shù)體內(nèi),減少了2個參數(shù)的多次傳遞;
把函數(shù)ReplaceLocalFiles中具體的copy2操作進行了提取,因為bydir和非bydir最終都會走到這個操作;
把函數(shù)ReplaceFiles中對函數(shù)ReplaceLocalFiles的操作進行了提取,同時把函數(shù)ReplaceAllFiles和ReplaceFiles進行了合并。
優(yōu)化后的結(jié)果看起來有沒有清爽很多?
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。