继续完善我的第一个Python程序。
昨天晚上学了lambda,发现函数编程真是个有趣的东西,对于某些应用(例如我的这个行号处理工具),可以极大减少代码书写量。不过函数编程也有缺点:代码可读性似乎很差。我很怀疑下边这段代码自己3个月以后是否还能看懂:囧
#-*- coding: utf-8 -*-"""去除代码前行号的Python小工具-lambda版
Develop by YanXY"""importsys, refromPyQt4importQtCore, QtGui
app=QtGui.QApplication(sys.argv)
window=QtGui.QWidget()
window.resize(800,600)
window.setWindowTitle(u'去除代码前行号的Python小工具 - lambda版 - Develop by YanXY')
textBox=QtGui.QTextEdit()
textBox.setAcceptRichText(bool(0))
butOK=QtGui.QPushButton(u"去除行号")
layout=QtGui.QHBoxLayout()
layout.addWidget(textBox)
layout.addWidget(butOK,alignment=QtCore.Qt.AlignTop)
window.setLayout(layout)defCutLineNum():#核心在这,注意有个换行号,实际上只有一行代码,够酷吧 -_-textBox.setText(''.join(map(lambdax:re.compile(r'\D*\d+\s?[.|:|\]|\)]?\s?'). \
sub('', x,count=1),unicode(textBox.toPlainText()).splitlines(1))))
QtCore.QObject.connect(butOK,QtCore.SIGNAL("clicked()"),CutLineNum)
window.show()
sys.exit(app.exec_())
下面我们就来自内而外层层解构这行代码(上边的阴影部分):
(1)最内层是一个正则表达式替换,re.compile(r'\D*\d+\s?[.|:|\]|\)]?\s?')编译了了一个正则表达式,并返回了一个正则表达式对象。该正则表达式的含义请参看我的上一篇文章。
(2)第二层:sub( '', x,count = 1 )的含义是用空字符替换字符串变量x中第一个匹配上述正则表达式的子串,也就是删除了x的行号。
(3)第三层:用匿名函数将上述两层包装起来,这时需要用到lambda语句,它用来创建一个匿名函数(没和名字绑定的函数): 例如一个最简单的lambda函数形如
lambdax: x+1#它等同于:defplus(x)returnx+1
lambda的方便之处在于它可以少写一个函数定义,“减少键盘的敲击”(《可爱的Python》里说的,这本书里同时也提到滥用lambda会严重影响代码可读性)。
(4)第四层,map函数,这是Python提供的一系列函数编程方法中的一个,t = map(func, s )函数将序列s中的每个元素传递给func函数做参数, 函数的返回值组成了列表 t, func函数必须有只有一个参数,例如:
a=[1,2,3,4,5,6]deffoo(x):return3*x
b=map(foo,a)#返回 b = [3, 6, 9, 12, 15, 18]
以上代码引自《Python 精要参考(第二版)》,里边有更多函数编程的介绍。这本书非常不错,我现在用它以及上边提到的《可爱的Python》这两本书来学Python,向大家推荐。我是上网下载后打印的,各有100页左右(《可爱的Python》只打印了“语法篇”)。对初学者来说,这两本小书比《Python 学习手册》要好得多,《Python 学习手册》像砖头一样,反正我是没毅力看。
在我的代码中,map函数用来从文本框中读取得字符串列表unicode(textBox.toPlainText()).splitlines(1))中,用第三层中的lambda函数替换每一行的行号,它返回了一个字符串列表(没有行号的)
(5)第五层,join方法,用来把一个字符串列表连接为一个单一的字符串,这个比较简单,不再多说。
(6)第六层,textBox.setText(……),把join后的字符串写回文本框,完成了。
实际上以上的思路就是我在上一篇文章中写出来的代码,只不过此处通过函数编程手法,把那些循环、函数定义、赋值、取值等写在一行里了。
方便吗?我觉得一点也没有,因为我的工作量是一样的,只不过少敲了几下键盘,(但多按了N次F5,调试总出错啊!)而且不太容易读懂。
至于效率,我猜应该是一样的,Python在内部应该也是把这一条语句解析成上边的一串指令来执行。不然呢?