Python FreshMan

★☆ Python新手的Blog ☆★
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

删除代码行号的Python小工具——lambda版

Posted on 2010-02-21 08:58  闫小勇  阅读(1679)  评论(3编辑  收藏  举报

继续完善我的第一个Python程序。

昨天晚上学了lambda,发现函数编程真是个有趣的东西,对于某些应用(例如我的这个行号处理工具),可以极大减少代码书写量。不过函数编程也有缺点:代码可读性似乎很差。我很怀疑下边这段代码自己3个月以后是否还能看懂:囧

 

# -*- coding: utf-8 -*-
"""
去除代码前行号的Python小工具-lambda版
Develop by YanXY
"""
import sys, re
from PyQt4 import QtCore, 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)

def CutLineNum():#核心在这,注意有个换行号,实际上只有一行代码,够酷吧 -_-
textBox.setText(''.join(map(lambda x: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函数形如

lambda x: x+1
#它等同于:
def plus(x)
return x+1

lambda的方便之处在于它可以少写一个函数定义,“减少键盘的敲击”(《可爱的Python》里说的,这本书里同时也提到滥用lambda会严重影响代码可读性)。

(4)第四层,map函数,这是Python提供的一系列函数编程方法中的一个,t = map(func, s )函数将序列s中的每个元素传递给func函数做参数, 函数的返回值组成了列表 t, func函数必须有只有一个参数,例如:

a = [1, 2, 3, 4, 5, 6]
def foo(x):
return 3*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在内部应该也是把这一条语句解析成上边的一串指令来执行。不然呢?