Python代码优化实践
来源:互联网 发布:windows 10企业版激活 编辑:程序博客网 时间:2024/05/24 04:16
最近在用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)continueelif (1 < filecounts):printandwritelog(u"文件 %s 有 %s 个路径,请使用指定路径方式进行替换" % (file , filecounts))continueelif (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点,优化的思路是:合并同类项,对于重复代码的部分,尽可能提取到共用逻辑中实现。
下面是优化后的代码:
#执行本地文件替换的具体操作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)continueelif (1 < filecounts):printandwritelog(u"文件 %s 有 %s 个路径,请使用指定路径方式进行替换" % (file , filecounts))continueelif (1 == filecounts):for line in context.split("\n"):filename = line.split("\\")[-1]if file == filename:targetfullpath = lineelse: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 = filepathif ":" 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进行了合并。
优化后的结果看起来有没有清爽很多?
如果大家有更好的优化建议,欢迎后台留言沟通。
获取持续更新,请关注「我在编程」
0 0
- Python代码优化实践
- 代码 优化 指南 实践
- python集合优化实践
- Python代码优化:优化原则
- Python代码优化:优化策略
- Python代码优化
- Python代码优化
- Python的代码优化
- 优化代码(Python)
- Python代码优化
- Python代码优化概要
- Python 代码性能优化
- python代码优化
- Python代码性能优化
- python代码优化
- Python代码性能优化
- python 代码优化
- python代码优化
- 《剑指offer》—10、矩形覆盖
- 自删除技术
- angularJs 个人初探笔记
- Objective-C 类,数据成员,函数成员,对象,
- Spring+SpringMVC+MyBatis+easyUI整合基础篇(三)搭建步骤
- Python代码优化实践
- 【华为面试】将输入的数字转换为大写形式
- javaScript 中变量
- Driver:模块参数、系统调用、字符设备驱动框架
- jqGrid单元格/行编辑模式下getRowData如何获取数据行
- hdu 2108 Shape of HDU
- Java 版 Prim 算法求最小生成树
- java wait用法详解
- NTP注意事项
原创粉丝点击
热门IT博客