1.6 使用glob读取多个文本文件

在很多商业应用中,需要对多个文件进行同样的或相似的处理。例如,你可能会从多个文件中选择数据子集,根据多个文件计算像总计和均值这样的统计量,或根据来自于多个文件的数据子集计算统计量。当文件数量增加时,手动处理文件的可能性会减小,出错的概率会增加。

读取多个文件的一种方法是在命令行中将包含输入文件目录的路径名写在Python脚本名称之后。要使用这种方法,你需要在脚本开头导入内置的os模块和glob模块。在脚本上方添加了import os和import glob语句之后,你就可以使用os模块和glob模块提供的所有功能了:

#!/usr/bin/env python3
from math import exp, log, sqrt
import re
from datetime import date, time, datetime, timedelta
from operator import itemgetter
import sys
import glob
import os

当导入了os模块之后,你就可以使用它提供的若干种路径名函数了。例如,os.path.join函数可以巧妙地将一个或多个路径成分连接在一起。glob模块可以找出与特定模式相匹配的所有路径名。os模块和glob模块组合在一起使用,可以找出符合特定模式的某个文件夹下面的所有文件。

要读取多个文件,需要再创建一个文本文件。

创建另一个文本文件

(1)打开Spyder IDE或一个文本编辑器(例如:Windows系统下的Notepad、Notepad++、Sublime Text;macOS系统下的TextMate、TextWrangler、Sublime Text)。

(2)在文本文件中写入下面8行(参见图1-13):

This
text
comes
from
a
different
text
file.

图1-13:Notepad++中的文本文件another_file_to_read.txt

(3)将文件保存在桌面上,文件名为another_file_to_read.txt。

(4)将下面几行代码添加到first_script.py的下方:

# 读取多个文本文件
print("Output #145:")
inputPath = sys.argv[1]
for input_file in glob.glob(os.path.join(inputPath,'*.txt')):
    with open(input_file, 'r', newline='') as filereader:
        for row in filereader:
            print("{}".format(row.strip()))

这个示例中的第一行代码与读取单个文本文件示例中的代码非常相似,只是在这个示例中,要提供一个目录路径名,而不是一个文件路径名。这里,要提供的路径指向包含了两个文本文件的目录。

第二行代码是for循环,使用os.path.join函数和glob.glob函数来找出符合特定模式的某个文件夹下面的所有文件。指向这个文件夹的路径包含在变量inputpath中,这个变量将在命令行中被提供。os.path.join函数将这个文件夹路径和这个文件夹中所有符合特定模式的文件名连接起来,这种特定模式可以由glob.glob函数扩展。这个示例使用的是模式*.txt来匹配由.txt结尾的所有文件名。因为这是一个for循环,所以这行中其余的代码你应该很熟悉了。input_file是一个占位符,表示由glob.glob函数生成的列表中的每个文件。这行代码的意义就是:对于匹配文件列表中的每个文件,做下面的操作……

余下的代码和读取单个文件的代码非常相似。以只读方式打开input_file变量,然后创建一个filereader对象。对于filereader对象中的每一行,除去行两端的空格、制表符和换行符,然后打印这一行。

(5)重新保存first _script.py。

(6)要读取这些文本文件,输入以下代码,如图1-14所示,然后按回车键:

python first_script.py "C:\Users\[Your Name]\Desktop"

图1-14:命令行窗口中的Python脚本和指向包含文本文件的桌面文件夹的路径

这样,你就在Python中读取了多个文本文件。你会看到以下内容被打印到屏幕上,在以前的输出之后(图1-15):

This
text
comes
from
a
different
text
file.
I'm
already
much
better
at
Python.

图1-15:first_script.py的输出,在命令行窗口中处理多个文本文件

学会这项技术的一个巨大好处是它可以规模化扩展。这个示例只是处理两个文本文件,但是它可以轻松地扩展为处理几十、几百或者几千甚至更多的文件。学习了如何使用glob.glob函数,仅花费手动处理的一小部分时间,就可以处理非常非常多的文件。