ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Python 代码优化实践

2021-06-17 21:52:42  阅读:180  来源: 互联网

标签:filepath Python 路径 实践 bydir 代码优化 printandwritelog file 替换


watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

 

最近在用 Python 写一个一键替换文件的脚本文件,大概的功能是,向程序传递一个本地或 SFTP 目录的参数,程序可以把指定目录所有文件替换到特定应用程序的对应目录。程序提供了如下 2 种命令行调用:

Usage: demo.py [sourcedir]
Usage: demo.py [sourcedir] bydir

第一种调用的实际操作是:读取特定应用程序目录所有文件,并获取全路径作为一个集合,再把参数文件夹中文件按文件名与集合中文件进行匹配,如果匹配上则执行替换操作。

第二种调用的实际操作是:按参数文件夹的目录存放的路径,完整替换到应用程序的对应目录。

下面是最初的代码实现:

#执行本地文件替换的具体操作 
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"替换文件个数有误%s" % file)
               
#判断如果是本地文件则直接调用替换函数,如果是网络路径,则先下载文件再替换
def RelpaceFiles(filepath, context, filecontext, softpath, bydir):     if ":" in filepath:         printandwritelog(u"提供的本地路径,走本地路径文件替换流程")         ReplaceLocalFiles(filepath, context, filecontext, softpath, bydir)    
   else:         printandwritelog(u"提供的FTP路径,先下载文件到本地后再执行替换流程")         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)

#先处理替换前的前置操作,环境准备好之后执行替换操作    
def ReplaceAllFiles(filepath, bydir):     softpath = checkinst()    
   if ("notinst" == softpath):         printandwritelog(u"没有检测到软件安装目录,请确认后重试")        
       return "error"   
   else:         context, filecontext = getallfiles(softpath)         RelpaceFiles(filepath, context, filecontext, softpath, bydir)

先简单说明下各函数的功能:

ReplaceLocalFiles:主要功能函数,实现具体的替换操作;

RelpaceFiles:根据传入参数判断是否是网络路径,如果是则先把文件下载到本地,然后调用ReplaceLocalFiles执行替换操作;

ReplaceAllFiles:做了一些环境准备的事情,然后调用实际的功能函数RelpaceFiles进行干活;

printandwritelog:记录日志并输出;

checkinst:检查目标程序是否安装,如果安装则返回安装路径;

getallfiles:获取目标应用程序的文件全路径集合;

checkcount:获取指定文件名在目标应用程序文件集合中出现的次数;

netutilex:一个独立的操作SFTP的库文件。

从目前的代码中能发现至少有 2 个地方可以优化:

  1. 函数之间需要传递的参数太多了,可以看看是否全部必要,考虑下如何精简;

  2. 部分业务逻辑太细化,有重复的代码实现,导致实现看起来比较臃肿。

     

对于第 1 点,优化的思路是:对于非所有函数都必须调用的参数,尽可能的固化到实际使用的函数中,避免各函数仅仅做了传递员的工作。

对于第 2 点,优化的思路是:合并同类项,对于重复代码的部分,尽可能提取到共用逻辑中实现。

下面是优化后的代码:

#执行本地文件替换的具体操作
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"替换文件个数有误%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))

#先处理替换前的前置操作,环境准备好之后执行替换操作
def ReplaceAllFiles(filepath, bydir):     sourceFileDir = filepath
   if ":" in filepath:        printandwritelog(u"提供的本地路径,走本地路径文件替换流程")
   else:        printandwritelog(u"提供的FTP路径,先下载文件到本地后再执行替换流程")        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)

具体的优化操作有:

把函数checkinst和getallfiles的调用实现放到了其返回值使用者 ReplaceLocalFiles 的函数体内,减少了2个参数的多次传递;

把函数 ReplaceLocalFiles 中具体的 copy2 操作进行了提取,因为bydir和非 bydir 最终都会走到这个操作;

把函数 ReplaceFiles 中对函数 ReplaceLocalFiles 的操作进行了提取,同时把函数 ReplaceAllFiles 和 ReplaceFiles 进行了合并。

优化后的结果看起来有没有清爽很多?

标签:filepath,Python,路径,实践,bydir,代码优化,printandwritelog,file,替换
来源: https://blog.51cto.com/sylan215/2919605

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有