Python 代码优化实践

最近在用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进行了合并。

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

原文地址:http://blog.51cto.com/sylan215/2140080

时间: 2024-11-05 17:34:20

Python 代码优化实践的相关文章

PYTHON 最佳实践指南(转)

add by zhj: 本文参考了The Hitchhiker's Guide to Python,当然也加入了作者的一些东西.The Hitchhiker's Guide to Python 的github地址是https://github.com/kennethreitz/python-guide,貌似还能用pip安装该包.先占个坑,后面有时间再把文章转过来 原文:PYTHON 最佳实践指南

python代码优化技巧

转自:http://www.douban.com/group/topic/31478102/ 这个资料库还有些不错的好文章: http://www.ibm.com/developerworks/cn/ 来看这篇<Python 代码性能优化技巧>http://www.ibm.com/developerworks/cn/linux/l-cn-python-optim/index.html 原文标题是代码性能优化,关键是性能优化,如果纯是代码优化则跟代码重构无异. 代码性能优化的本质:保证代码正确行

Python数据分析基础与实践 Python数据分析实践课程 Python视频教程

课程简介: Python数据分析基础与实践 Python数据分析实践课程 Python视频教程----------------------课程目录------------------------------├<章节1Python概况>├<章节2Python安装>├<章节3数据准备>├<章节4数据处理>├<章节5数据可视化>├<章节6网页数据抓取>├<章节7连接MySQL>├<章节8数据分析> 下载地址:百度网盘

分享《Python机器学习实践指南》(高清中文版PDF+高清英文版PDF+源代码)

下载:https://pan.baidu.com/s/11dGldpITOoUUJmS9eD5ENw Python机器学习实践指南(高清中文版PDF+高清英文版PDF+源代码) 中文和英文两版对比学习, 带目录书签,可复制粘贴:讲解详细并配有源代码. 其中,高清中文版如图: 原文地址:http://blog.51cto.com/3215120/2301528

分享《Python机器学习实践指南》+PDF+源码+Alexanfer T.Combs+黄申

下载:https://pan.baidu.com/s/1nb-Q7MtQ2dfBbx2Dir-rQA 更多资料分享:http://blog.51cto.com/14087171 Python机器学习实践指南(高清中文版PDF+高清英文版PDF+源代码) 高清中文版PDF,268页,带目录书签,彩色配图,文字可复制粘贴: 高清英文版PDF,324页,带目录书签,彩色配图,文字可复制粘贴: 中文和英文两版对比学习: 讲解详细并配有源代码. 其中,高清中文版如图: 原文地址:http://blog.5

Python入门经典. 以解决计算问题为导向的Python编程实践(高清版)PDF

Python入门经典. 以解决计算问题为导向的Python编程实践(高清版)PDF百度网盘链接:https://pan.baidu.com/s/1juLsew8UiOErRheQPOuTaw 提取码:fssd 复制这段内容后打开百度网盘手机App,操作更方便哦内容简介 · · · · · · <Python入门经典:以解决计算问题为导向的Python编程实践>是一本系统而科学的Python入门教程,美国密歇根州立大学等多所美国知名高校采用其作为编程语言的入门教材,被奉为经典.它不仅从计算机教学

机器学习实践:《Python机器学习实践指南》中文PDF+英文PDF+代码

机器学习是近年来渐趋热门的一个领域,同时Python 语言经过一段时间的发展也已逐渐成为主流的编程语言之一.<Python机器学习实践指南>结合了机器学习和Python 语言两个热门的领域,通过利用两种核心的机器学习算法来将Python 语言在数据分析方面的优势发挥到极致. 共有10 章.第1 章讲解了Python 机器学习的生态系统,剩余9 章介绍了众多与机器学习相关的算法,包括各类分类算法.数据可视化技术.推荐引擎等,主要包括机器学习在公寓.机票.IPO 市场.新闻源.内容推广.股票市场.

随笔记:Python初实践

有一同事要离职了,我负责交接一个用Python同步数据的项目. 之前木有做过Python,周休,做个简单的查询数据库,小练一下手. 包含: 安装 连接.查询MySQL 列表 元组 for循环 while循环 下载 上Python官方网站,下载Python安装包,目前流行的版本为2.7和3.x版本,这两个大版本之间语法有些差异,并不兼容. 这次项目用到的是2.7版本,所以,先学习此. 目前,下载页面为:https://www.python.org/downloads/release/python-

Python 最佳实践指南

粗粗粗略地过了一遍,大体捞了一些东西出来,大段大段英文太费眼了,回头细读在更新进来 浓缩版,20分钟可大体过完,然后根据自己需要去看详细的吧 整体内容还是很不错的,建议细读英文 PS:文档含有巨量的TODO(没写空白着待补充的),不过但从目录上来看还是很强大滴,相信完善后,会成为一份很牛逼的指南(难度比官方指南高一点点) 第零部分 Getting Started 链接 不解释,不翻译,自个看….真的没啥(每本入门书籍第一章…) 第一部分 Writing Great Code Structurin