如何编写Unix管道风格的Python代码
2010-09-22 11:10:40 来源:WEB开发网看过 SICP 就知道,其实函数式编程中的map, filter 都可以看作是管道思想的应用。但其实管道的思想不仅可以在函数式语言中使用,只要语言支持定义函数,有能够存放一组数据的数据结构,就可以使用管道的思想。
一个日志处理任务
应用场景如下:
◆ 某个目录及子目录下有一些 web 服务器的日志文件,日志文件名以 access-log 开头
◆ 日志格式如下
81.107.39.38 - ... "GET /ply/ply.html HTTP/1.1" 200 97238
81.107.39.38 - ... "GET /ply HTTP/1.1" 304 -
其中最后一列数字为发送的字节数,若为 ‘-’ 则表示没有发送数据
◆目标是算出总共发送了多少字节的数据,实际上也就是要把日志记录的没一行的最后一列数值加起来
我不直接展示如何用 Unix 管道的风格来处理这个问题,而是先给出一些“不那么好”的代码,指出它们的问题,最后再展示管道风格的代码,并介绍如何使用 generator 来避免效率上的问题。
问题并不复杂,几个 for 循环就能搞定:
sum = 0
for path, dirlist, filelist in os.walk(top):
for name in fnmatch.filter(filelist, "access-log*"):
# 对子目录中的每个日志文件进行处理
with open(name) as f:
for line in f:
if line[-1] == '-':
continue
else:
sum += int(line.rsplit(None, 1)[1])
利用 os.walk 这个问题解决起来很方便,由此也可以看出 python 的 for 语句做遍历是多么的方便,不需要额外控制循环次数的变量,省去了设置初始值、更新、判断循环结束条件等工作,相比 C/C++/Java 这样的语言真是太方便了。看起来一切都很美好。
赞助商链接