更新时间:2021-11-21 18:15:28
当一个人太执着于某一个东西的时候,
会错过很多美好的东西!
Python值得学习的一个工具,不要局限在当前使用的语言中。
在大概3个月之前,Python对我来说一直是个迷。然而,就在3个月前我经理给我一个任务——删除(替换)所有项目源码文件中包含特定几行内容的 所有注释。整个项目源码的大小有1G,在Linux服务器(中高档)上编译需要半个多小时,可见代码量之大,不可能手动去一个一个改。肯定得用脚本去处 理,于是我想到了Python。在这之前没有接触过Python,花了2个星期一顿恶补之后,总算顺利交差了。
一直很想和大家分享一下碰到的问题及我如何解决的(可能我的方案并不好,但是他能够解决我的问题),但一直拖到现在是因为我感觉我还对Python 的了解还不够。因为要在短时间内完成上面交下来的任务,在学习Python的时候,都是走马观花,对解决自己的问题不相关的直接跳过,看资料也静不下心, 脑海里都是问题。前几天我静下心把Python的书从头到尾浏览了一遍,感觉现在是时候要进行总结了。
本文的主要内容如下:
项目源码很大,属于C/C++混合的那种,编程风格也很多样,有'.c'、'.cc'、'cpp'、'.h'、'.hh'等文件。我要完成的任务是:把包含特定几行内容的注释删掉,如(声明:下面的内容只是我随便举的一个例子,项目源码中不涉及下面的内容。)
/*
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*/
但是格式有很多种,如有的在“ Copyright 2002 Sun Microsystems, Inc. All rights reserved.”前面有一段关于本源码文件的描述、有的在“from this software without specific prior written permission.”后面有一段关于本源码文件的描述、有的是C++风格的注释用"//",而不是“/**/”、还有的没有
“ * - Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.”等等还有其他一些。总之一句话,我要删除的包含特定几行内容的注释有很多中格式!
于是我决定要用Python来编写脚本处理。要匹配特定的内容,我想到了用正则表达式,但苦于不知道如何去构建正则来匹配上面描述的内容(您知道的话,希望能够告诉我)!我只有另辟路径了。
我的思路——要删除所有项目源码中包含特定几行内容的注释,脚本要满足以下几点功能:
上面的几点的处理步骤可以表示如下:
Step 1:输入要处理源码文件夹名,或者源码文件名;
Step 2:如果是文件名,检查文件的类型是否为'.c'、'.cc'、'cpp'、'.h'、'.hh',否则不处理;
Step 3:检查文件是否是软连接,如果是软连接则不处理;
Step 4:查找文件中是否存在匹配的注释,存在则删掉,否则不处理;
Step 5:如果是文件夹,则对文件夹中的每个文件、文件夹进行处理,转Step2.
思路很明确,关键是如何查找文件中是否包含匹配的内容,并删除!还有就是,对于一个没用过Python等脚本语言的人来说,如何编码实现也是一个问题!
如何确定注释是否为包含特定几行内容的注释?我的思路如下:(因为正则表达式学的不好,只有通过下面的方法了)
废话我不多说了,直接按照上面的实例实现代码,如果你对Python不熟,请参阅相关资料。
#!/usr/bin/env python
#Filename: comment.py
import os, sys, fileinput
#-------------------------------------------------------------
def usage():
print u'''
help: comment.py <filename | dirname>
[dirname]: Option, select a directory to operate
[filename]: Option, select a file to operate
Example: python comment.py /home/saylor/test
'''
#--------------------------------------------------------------
def commentFile(src, fileList):
'''
description: comment files
param src: Operate file name
'''
#if file exist?
if not os.path.exists(src):
print 'Error: file - %s doesn\'t exist.'% src
return False
if os.path.islink(src):
print 'Error: file - %s is just a link, will not handle it.'
return False
filetype = (os.path.splitext(src))[1]
if not filetype in ['.c','.h']:
return False
try:
if not os.access(src, os.W_OK):
os.chmod(src, 0664)
except:
print 'Error: you can not chang %s\'s mode.'% src
try:
inputf = open(src, 'r')
outputfilename = src + '.tmp'
outputf = open(outputfilename, 'w')
beginLine = 0
endLine = 100000000
isMatched = False
#-----find the beginLine and endLine -------------------
for eachline in fileinput.input(src):
if eachline.find('/*') >= 0:
beginLine = fileinput.lineno()
if eachline.find('Copyright 2002 Sun Microsystems, Inc. All rights reserved.') >= 0:
isMatched = True
if eachline.find('*/') >= 0 and isMatched:
endLine = fileinput.lineno()
break
#-----delete the content between beginLine and endLine-----
print beginLine, endLine
lineNo = 1
for eachline in inputf:
if lineNo < beginLine:
print eachline
outputf.write(eachline)
elif lineNo > endLine:
print eachline
outputf.write(eachline)
lineNo = lineNo + 1
inputf.close()
outputf.close()
os.rename(outputfilename, src)
fileList.append(src)
except:
print 'Error: unexcept error.'
inputf.close()
outputf.close()
return True
#--------------------------------------------------------------
def commentDir(src, fileList):
'''
description:
comment files in src(dir)
param src:
operate files in src(dir)
'''
#if dir exist?
if not os.path.exists(src):
print 'Error: dir - %s is not exist.'%s (src)
return False
filelists = os.listdir(src)
for eachfile in filelists:
eachfile = src + '/' +eachfile
if os.path.isdir(eachfile):
commentDir(eachfile, fileList)
elif os.path.isfile(eachfile):
commentFile(eachfile, fileList)
return True
#--------------------------------------------------------------
def main():
if len(sys.argv) < 2:
usage()
sys.exit(1)
src = sys.argv[1]
if os.path.isdir(src):
dire = os.path.abspath(src)
dirFlag = True
elif os.path.isfile(src):
fl = os.path.abspath(src)
dirFlag = False
else:
print 'Error'
fileList = []
if dirFlag:
commentDir(dire, fileList)
else:
commentFile(fl, fileList)
if fileList:
print 'Successful handle file: ...'
for eachfile in fileList:
print eachfile
print 'Done'
return True
#--------------------------------------------------------------
if __name__ == '__main__':
main()
Python入门我强烈推荐下面的资料,深入学习请阅读其它资料:
《A Byte of Python》http://www.swaroopch.com/notes/Python
《简明 Python 教程》http://woodpecker.org.cn/abyteofpython_cn/chinese/
Python的设计哲学是“优雅”、“明确”、“简单”。因此,Perl语言中“总有多种方法来做同一件事”的理念在Python开发者中通常是难 以忍受的。Python开发者的哲学是“用一种方法,***是只有一种方法来做一件事”。在设计Python语言时,如果面临多种选择,Python开发者 总会拒绝花哨的语法,而选择明确的没有或者很少有歧义的语法。由于这种设计观念的差异,Python源代码通常认为比Perl具备更好的可读性。
Python开发人员尽量避开不成熟或者不重要的优化。一些针对非重要部位的加快运行速度的补丁通常不会被合并到Python内。所以很多认为 Python很慢。不过,根据二八定律,大多数程序对速度要求不高。在某些对运行速度要求很高的情况,Python程序员倾向于使用JIT技术,或者用使 用C/C++语言改写这部分程序。目前可用的JIT技术是Pysco。Cython可以将Python代码转换成C代码。
相对于Lisp这种传统的函数式编程语言,Python对函数式编程只提供了有限的支持。有两个标准库(functools, itertools)提供了Haskell和Standard ML中久经考验的函数式编程工具。
虽然Python可能被粗略地分类为「脚本语言」(script language),但实际上一些大规模软件开发计划例如Zope、Mnet及BitTorrent,Google也广泛地使用它。Python的支持者 较喜欢称它为一种高阶动态编程语言,原因是「脚本语言」泛指仅作简单编程任务的语言,如shell script、JavaScript等只能处理简单任务的编程语言,並不能与Python相提并论。
Python本身被设计为可扩展的。并非所有的特性和功能都集成到语言核心。可以使用C语言、C++、Cython来编写扩展模块。Python解 释器本身也可以被集成到其它需要脚本语言的程序内。因此,很多人还把Python作为一种「胶水语言」(glue language)使用。使用Python将其他语言编写的程序进行集成和封装。在Google内部的很多项目使用C++编写性能要求极高的部分,然后用 Python调用相应的模块。
Python的特点:
#!/usr/bin/env python
# Filename: using_name.py
if __name__ == '__main__':
print 'This program is being run by itself'
else:
print 'I am being imported from another module'
#!/usr/bin/env python
# Filename: print_tuple.py
age = 22
name = 'Swaroop'
print '%s is %d years old' % (name, age)
print 'Why is %s playing with that python?' % name
最后,感谢实习所在公司给我足够的时间和机会去学习新的东西。