应用 Python 解决一些实际问题
http://www.ibm.com/developerworks/cn/linux/tips/l-python/index.html
Python 是一种简洁优美的脚本语言,它的诸多优点使它在完成某些任务时轻松自如。本文通过几个具体的例子阐明了这一点。
Python 是一种简洁优美的编程语言,它具有面向对象的特征,较好的粘合其他语言的能力及跨平台性。然而我认为同样重要的是, 它简单易学,书写代码简洁快速。此外,Python 提供了较多的模快,包含了相当多的功能,所以只要有一个可行的想法,那么用 Python 解决起来会是比较容易的。下面几个例子都源于我遇到的一些实际问题。借助于 Python,这些问题的解决都显得轻而易举。
回页首
某些软件在工作时会自动生成一些备份文件。比如我用 Vim 做文本编辑,用 Autocad 绘图时,这些程序都会自动生成一些备份的文件。随着文件数量的增长,每隔一段时间就要清理一下。当然可以选择手工清理,不过考虑到这些文件是分散在不同的目录下,而且数量比较多,所以手工清理还是有些麻烦。于我写了一个简单的 Python 脚本来自动完成这一任务。下面这段代码扫描D盘下的所有目录,并删除目录下的有关备份文件:
from os.path import walk, join, normpath from os import chdir, remove def scan(arg, dirname, names) for file in names: 1 if file[-1:]=="~" or file[-4:]==".bak": 2 files = normpath(join(dirname,file)) 3 chdir(dirname) 4 print "deleting", files 5 remove(file) 6 print "done!" if __name__== "__main__": path = chdir('d:') 7 walk(path, scan, 0) |
对以上代码的简单分析和解释:
- 基本的想法是利用脚本对各个目录进行扫描,对目录下每一个文件进行判断(1句),如果是某个程序生成的备份文件就删除掉(5句)。
- 备份文件的扩展名都有一定的特征,比如 Vim 备份文件的最后一个字符是波浪号~,而 Autocad 的备份则以 bak 结束。这些特征是判断一个文件是否应该被删除的依据。
- 7 句 walk(path, scan, 0) 是一个 Python 的内置函数。用来遍历目录 path。显而易见借助于 Python 提供的这个函数,扫描目录的工作比较轻松地完成了,从而使编程的难度降低许多。
- 最后要说明的一点是,删除某个文件时要知道它的绝对路径而且要在那个文件的所在目录下进行,否则 Python 会提示找不到要处理的文件。2 句得到了文件的绝对路径,3 句 chdir(dirname) 则把当前的目录变成要删除文件的所在目录。
回页首
这个问题的提出也是来自实际的需要。 我在阅读与课题有关的各种格式的电子文档时,有时发现包含在文档里面的图像很有用,因为这些图像可以在论文或报告中直接引用, 所以最好能把它们保存下来。 在 Linux 下工作时我用过 Pdfimages,那是一个从 PDF 文档中提取图像的工具。但我希望能找到一个工具可以同时快速处理不同格式的文档,而且能在 Windows 下工作。感 谢 Python,它使我能用比较简单的代码去实现这样一个工具。
基本的想法是先读取要处理的文档,然后在其中找到图像部分。因为各种图像在起始部分都包含了自己的标识。比如JPEG图像的标识是JFIF,PNG的是PNG。找到这些标识后读取包含这个图像的相应字节,再把它以二进制格式保存下来.根据这个想法,代码可以分为两部分:寻找图像和保存图像。下面的这两段代码用来从一个PowerPoint文档NORFA_COD.ppt中提取图像,其中第一部分的代码如下:
import sys import os import string 1 headers=[("JFIF", 6, "jpg"), ("GIF", 0, "gif"), ("PNG", 1, "png")] 2 marker=[] 3 filename = "d:articlepptNORFA_COD.ppt" try: 4 fid = open(filename, 'rb') except: 5 sys.exit(1) 6 numlin = len(fid.readlines()) 7 fid .seek(0) 8 i = 0; s = 0 9 curlin = fid.readline() while i < numlin: for flag, offset, ext in headers: 10 index = string.find(curlin, flag) if index < 0: 11 continue else: 12 pos = s + index -offset 13 marker.append((pos, ext)) 14 s = s + len(curlin) 15 curlin = fid.readline() 16 i += 1 |
以上代码首先把要处理的文件以二进制格式逐行读入(9句),然后在其中寻找有没有包含1句headers里的图像标识。如果没有找到,就读取下一行(11句)。如果发现的话,就把图像的起始位置和标识记录在一个字典marker里(12-13句)。在扫描完整个文档后,可以得到一个包含图像信息的字典marker。
有了marker里的信息,就可以进行图像的保存工作了。这部分的代码是:
17 fid.seek(0) 18 j = len(marker) 19 imgnum = 0 if j == 0: 20 print "No images included in the document" 21 sys.exit(1) for i in range(0, j): 22 if i == j-1: 23 info = marker[i] 24 thispos = info[0] 25 thisext = info[1] 26 nextpos = s 27 gap = nextpos - thispos 28 fid.seek(thispos) 29 data = fid.read(gap) 30 imgname = "imgname%02d.%s" % (i, thisext) 31 fid1 = open(imgname, 'wb') 32 fid1.write(data) 33 fid1.close() 34 imgnum += 1 else: 35 info = marker[i] 36 thispos = info[0] 37 thisext = info[1] 38 nextinfo = marker[i+1] 39 nextpos = nextinfo[0] 40 gap = nextpos - thispos 41 fid.seek(thispos) 42 data = fid.read(gap) 43 imgname = "imgname%02d.%s" % (i, thisext) 44 fid1 = open(imgname, 'wb') 45 fid1.write(data) 46 fid1.close() 47 imgnum += 1 48 fid.close() 49 print "%02d imgaes have benn extracted" % imgnum |
下面来说明一下如何存储图像。首先注意到虽然定位一个图像的起始位置比较容易,但要确定它的结束位置却比较困难。我用了一个间接的方法来解决这个问题,那就是先读取当前图像的起始位置,至于它的结束位置则取为下一个图像(如果有的话)的起点位置(35-41句); 如果当前的图像是文档中最后的一个,那么结束位置则取为文档的结束位置(23-28句)。这样做的好处是,由于存储的范围是从当前图像的起始位置到下一幅图像的起始位置,这就保证了当前图像可以被完整的保存下来,不用担心它被中途截断。缺点是保存的数据中不仅包括了当前的图像,还有一些其他的内容。也就是说图像中包含了一些冗余的数据,这样就造成了文件的尺寸比图像实际的尺寸要大。当然这不会影响它的浏览,因为图形软件在读取这些文件时会把冗余的部分给截断掉,不过如果想要在自己的论文或报告中引用这些图像的话,最好还是要给它们"廋身"一下。方法也很简单,只要用图形软件把这些图像重新保存一遍就可以恢复原来的尺寸了。
此外,从上面的代码不难看出,要处理更多种类的图像,只要把有关图像的格式信息添加到headers就可以了. 而被处理的文档可以是任意的格式.
回页首
最近我做实验时需要把得到的数据用Matlab绘图并保存下来。一个小问题是原始的数据文件中不仅有数据还有一些注释的部分(注释部分在数据之前,每行以#开头)。直接用Matlab绘图比较麻烦,因为不能直接处理数据,所以或者要把数据单独提取出来,另存成一个文件。或者就要用Matlab写一个过滤文本的程序。不过Matlab处理文本并不是它的强项。 所以这两个办法我都不很满意。Python再次给我提供了解决的方案。一方面Python具有很强的文本处理能力,另一方面Python对Matlab这种交互式的程序提供了直接调用的的途径,所以写一个Python脚本来完成这一任务无疑是比较合适的。下面是实现的代码:
import os import string 1 filepath = "d:expchgeff_lar_1" 2 filename="chgeff_lar_1" 3 fid = open(filepath, 'r') 4 lines = fid.readlines() 5 fid.close() 6 x = []; y = [] 7 for line in lines: 8 if line[0]=="#" or len(line)==1: 9 continue 10 else: 11 xval, yval = string.split(line) 12 x.append(float(xval)) 13 y.append(float(yval)) 14 fid = open(filename+'.m', 'w') 15 fid.write(""" 16 x = %s 17 y = %s 18 plot(x, y) 19 xlabel('Particle diameter (nm)') 20 ylabel('Charging efficiency') 21 print -deps %s.eps 22 pause(10) 23 """ % (x, y, filename)) 24 fid.write("exit") 25 fid.close() 26 cmd = "d:matlab6p5binwin32matlab.exe -nodesktop -r " + filename 27 os.system(cmd) |
以上6-13句实现两个功能,一是过滤文本(8-9句),通过检查每一行的第一个字符及行的长度,把注释行和空行给去掉。二是把读到的每一行数据自动分配到两个变量x,y中(10-13句)。然后Python把一组Matlab代码(16-24句)写到文件filename.m中。最后利用os模块的system函数调用Matlab绘图及保存(26-27句)。从这个例子也可以看出,Python和其他语言协同工作的能力是比较强的。
回页首
Python是一种优美高效的脚本语言。它简单易学,代码的书写也很简洁明了。在完成某些任务时,使用Python可以使你专心于你的问题,而不需要把很多时间花在编程上。借助于Python的众多模块,编程的难度降低了许多, 时间也减少了。我想对于一个普通的用户(比如我)而言,学习一门语言的最终目的是用它来解决实际的问题,提高工作效率。从这个角度说,Python绝对是一个值得考虑的选择。
==========================================================
python应用领域介绍
Python作为一种功能强大且通用的编程语言而广受好评,它具有非常清晰的语法特点,适用于多种操作系统,目前在国际上非常流行,正在得到越来越多的应用。
下面就让我们一起来看看它的强大功能:
Python(派森),它是一个简单的、解释型的、交互式的、可移植的、面向对象的超高级语言。这就是对Python语言的最简单的描述。
Python有一个交互式的开发环境,因为Python是解释运行,这大大节省了每次编译的时间。Python语法简单,且内置有几种高级数据结构,如字典、列表等,使得使用起来特别简单,程序员一个下午就可学会,一般人员一周内也可掌握。Python具有大部分面向对象语言的特征,可完全进行面向对象编程。它可以在MS-DOS、Windows、Windows NT、Linux、Soloris、Amiga、BeOS、OS/2、VMS、QNX等多种OS上运行。
编程语言
Python语言可以用来作为批处理语言,写一些简单工具,处理些数据,作为其他软件的接口调试等。Python语言可以用来作为函数语言,进行人工智能程序的开发,具有Lisp语言的大部分功能。Python语言可以用来作为过程语言,进行我们常见的应用程序开发,可以和VB等语言一样应用。Python语言可以用来作为面向对象语言,具有大部分面向对象语言的特征,常作为大型应用软件的原型开发,再用C++改写,有些直接用Python来开发。
数据库
Python在数据库方面也很优秀,可以和多种数据库进行连接,进行数据处理,从商业型的数据库到开放源码的数据库都提供支持。例如:Oracle,Ms SQL Server等等。有多种接口可以与数据库进行连接,至少包括ODBC。有许多公司采用着Python+MySql的架构。因此,掌握了Python使你可以充分利用面向对象的特点,在数据库处理方面如虎添翼。
Windows编程
Python不仅可以在Unix类型的操作系统上应用,同样可以在Windows系统里有很好的表现。通过添加PythonWin模块,就可以通过COM形式调用和建立各种资源,包括调用注册表、ActiveX控件以及各种COM等工作,最常见的例子就是通过程序对Office文档进行处理,自动生成文档和图表。
通过Python,还可以利用py2exe模块生成exe应用程序。还有许多其他的日常维护和管理工作也可以交给Python来做,从而减少维护的工作量。利用Python,你还可以开发出象VB,VC,Delphi那样的GUI程序,但却可以在多个平台上执行。这在许多方面并不逊色于Java。
多媒体
利用PIL、Piddle、ReportLab等模块,你可以处理图象、声音、视频、动画等,从而为你的程序添加亮丽的光彩。动态图表的生成、统计分析图表都可以通过Python来完成。另外,还有OpenGL。利用PyOpenGl模块,你可以非常迅速的编写出三维场景。
科学计算
Python可以广泛的在科学计算领域发挥独特的角色。有许多模块可以帮助你在计算巨型数组、矢量分析、神经网络等方面高效率完成工作。尤其是在教育科研方面,可以发挥出独特的优势。
网络编程
Python可以非常方便的完成网络编程的工作,提供了众多的解决方案和模块,可以非常方便的定制出自己的服务器软件,无论是c/s,还是b/s模式,都有很好的解决方法。
工具集:
Soket编程
CGI,Freeform
Zope,CMF,Plone,Silva,Nuxeo CPS...
WebWare
Twisted
CherryPy
SkunkWeb
Quixote
4Suite Server
Spyce
Albatross
Cheetah
mod_python
协议:
http
ftp
gopher
XML-PRC
SOAP
POP
SMTP
图形用户界面
Python可以非常方便的实现GUI编程,通过Tkinter,wxPython,QT等等模块,你就可以根据需要编写出强大的跨平台的用户界面程序。
开发环境与编辑器
Python程序的开发工具比较多,目前主要的工具既有IDLE,PythonWin这样的免费工具, 也有一些商业性的工具。通过这些工具,可以让你更为快速的完成工作。
集成开发环境(IDE):
IDLE:这是Python里边自带的,基本上可以满足一般开发需要,请参考cnIDLE。
PythonWin:这是基于Windows平台的编辑开发环境,基本上可以满足一般开发需要。
PythonWorks Pro
Wing IDE
Komodo
代码编辑器:
LEO:完全由Python编写的程序代码编写辅助工具,可运行在多种操作系统中,支持独特的程序代码管理方式。
gVim:相当专业的代码编辑器,可运行在多种操作系统中,支持Python扩展。
Emacs:Unix系统中常用的工具。
SciTE:简单易用的代码编辑器,支持unicode编辑。
嵌入和扩展
Python可以嵌入到其它应用程序中,也可以通过C/C++编写扩展模块,从而可以提高程序的运行速度或者完成只有通过C/C++才能完成的工作。现在Python已经可以和C#相结合,并且结合到Visual Studio里边,实现微软的.Net思想。如果你会C语言,再学习Python,这将是一个非常棒的一种选择。
如果你掌握了Python,想在Java里应用它,你可以采用Jython。Jython是采用Java语言实现的Python。这样,你只要按照Python的语法,就可以调用Java的各种类库,快速的编写出基于Java的程序。也就是通过Jython,编写Java程序。这样就可以更为快速的实现Java的功能。Python在面向对象方面和Java是相通的。
除了c/c++和java, Python 目前还可以和Delphi、VB结合。
游戏编程
Python在很早的时候就是一种游戏编程的辅助工具。在《星球大战》中扮演了重要的角色。在“阿贝斯(Abyss)”、“星球之旅(Star Trek)”、“Indiana Jones”超级大片中担当特技和动画制作的工业光魔公司(Industrial Light)就采用Python制作商业动画。目前,通过Python完全可以编写出非常棒的游戏程序。
企业与政务应用
目前,Python已经成功的实现企业级应用,在全球,已经有很多公司采用Python进行企业级软件的开发和应用,比如:ERP和CRM这样的应用。同时,通过Python技术,成功的实现了许多政务应用。
用Python写的较大的系统有:
Zope:一个应用程序服务器,具有内容管理、团队开发、XML、面向对象、SOAP接口等一系先进特性,且开放源码。参见:www.zope.com。
Gadfly:一个用Python写的面向对象关系型数据库,具有小巧、快速、可移植性好,具有大部分SQL语言特性,且开放源码。参见:http://www.chordate.com/gadfly.html。
还有一些比较有名的公司也在用Python进行原型的开发,如Microsoft、IBM等,还有:
红帽(Red Hat )曾用Python和Tk一起成功开发配置和管理操作系统的可视界面。整个系统可以全面控制Linux操作系统,并根据用户选择对配置文件作自动更新。
Infoseek在其公用搜索引擎使用了Python。该公司还用Python对其软件进行定制,使最终用户能对该网站内容进行方便下载。