3.1415926535
8979323846
2643383279
10.1.2 文件路径
当你将类似pi_digits.txt这样的简单文件名传递给函数open() 时,Python将在当前执行的文件(即.py程序文件)所在的目录中查找文件。
根据你组织文件的方式,有时可能要打开不在程序文件所属目录中的文件。例如,你可能将程序文件存储在了文件夹python_work中,而在文件夹python_work中,有一个名为
text_files的文件夹,用于存储程序文件操作的文本文件。虽然文件夹text_files包含在文件夹python_work中,但仅向open() 传递位于该文件夹中的文件的名称也不可行,因为Python 只在文件夹python_work中查找,而不会在其子文件夹text_files中查找。要让Python打开不与程序文件位于同一个目录中的文件,需要提供文件路径 ,它让Python到系统的特定位置
去查找。
由于文件夹text_files位于文件夹python_work中,因此可使用相对文件路 径来打开该文件夹中的文件。相对文件路径让Python到指定的位置去查找,而该位置是相对于当前运行的程
序所在目录的。在Linux和OS X中,你可以这样编写代码:
with open('text_files/filename.txt') as file_object:
这行代码让Python到文件夹python_work下的文件夹text_files中去查找指定的.txt文件。在Windows系统中,在文件路径中使用反斜杠(\ )而不是斜杠(/ ):
with open('text_files\filename.txt') as file_object:
你还可以将文件在计算机中的准确位置告诉Python,这样就不用关心当前运行的程序存储在什么地方了。这称为绝对文件路径 。在相对路径行不通时,可使用绝对路径。例如,
如果text_files并不在文件夹python_work中,而在文件夹other_files中,则向open() 传递路径'text_files/ filename.txt' 行不通,因为Python只在文件夹python_work中查找
该位置。为明确地指出你希望Python到哪里去查找,你需要提供完整的路径。
绝对路径通常比相对路径更长,因此将其存储在一个变量中,再将该变量传递给open() 会有所帮助。在Linux和OS X中,绝对路径类似于下面这样:
file_path = 'homeehmatthes/other_files/text_files/filename.txt'
with open(file_path) as file_object:
而在Windows系统中,它们类似于下面这样:
file_path = 'C:\Users\ehmatthes\other_files\text_files\filename.txt'
with open(file_path) as file_object:
通过使用绝对路径,可读取系统任何地方的文件。就目前而言,最简单的做法是,要么将数据文件存储在程序文件所在的目录,要么将其存储在程序文件所在目录下的一个文件
夹(如text_files)中。
注意 Windows系统有时能够正确地解读文件路径中的斜杠。如果你使用的是Windows系统,且结果不符合预期,请确保在文件路径中使用的是反斜杠。
10.1.3 逐行读取
读取文件时,常常需要检查其中的每一行:你可能要在文件中查找特定的信息,或者要以某种方式修改文件中的文本。例如,你可能要遍历一个包含天气数据的文件,并使用天
气描述中包含字样sunny的行。在新闻报道中,你可能会查找包含标签<headline> 的行,并按特定的格式设置它。
要以每次一行的方式检查文件,可对文件对象使用for 循环:
file_reader.py
❶ filename = 'pi_digits.txt'
❷ with open(filename) as file_object:
❸ for line in file_object:
print(line)
在❶处,我们将要读取的文件的名称存储在变量filename 中,这是使用文件时一种常见的做法。由于变量filename 表示的并非实际文件——它只是一个让Python知道到哪里
去查找文件的字符串,因此可轻松地将'pi_digits.txt' 替换为你要使用的另一个文件的名称。调用open() 后,将一个表示文件及其内容的对象存储到了变
量file_object 中(见❷)。这里也使用了关键字with ,让Python负责妥善地打开和关闭文件。为查看文件的内容,我们通过对文件对象执行循环来遍历文件中的每一行(见
❸)。
我们打印每一行时,发现空白行更多了:
3.1415926535
8979323846
2643383279
为何会出现这些空白行呢?因为在这个文件中,每行的末尾都有一个看不见的换行符,而print 语句也会加上一个换行符,因此每行末尾都有两个换行符:一个来自文件,另一
个来自print 语句。要消除这些多余的空白行,可在print 语句中使用rstrip() :
filename = 'pi_digits.txt'
with open(filename) as file_object:
for line in file_object:
print(line.rstrip())
现在,输出又与文件内容完全相同了:
3.1415926535
8979323846
2643383279
10.1.4 创建一个包含文件各行内容的列表
使用关键字with 时,open() 返回的文件对象只在with 代码块内可用。如果要在with 代码块外访问文件的内容,可在with 代码块内将文件的各行存储在一个列表中,并
在with 代码块外使用该列表:你可以立即处理文件的各个部分,也可推迟到程序后面再处理。
下面的示例在with 代码块中将文件pi_digits.txt的各行存储在一个列表中,再在with 代码块外打印它们:
filename = 'pi_digits.txt'
with open(filename) as file_object:
❶ lines = file_object.readlines()
❷ for line in lines:
print(line.rstrip())
❶处的方法readlines() 从文件中读取每一行,并将其存储在一个列表中;接下来,该列表被存储到变量lines 中;在with 代码块外,我们依然可以使用这个变量。在❷
处,我们使用一个简单的for 循环来打印lines 中的各行。由于列表lines 的每个元素都对应于文件中的一行,因此输出与文件内容完全一致。
10.1.5 使用文件的内容
将文件读取到内存中后,就可以以任何方式使用这些数据了。下面以简单的方式使用圆周率的值。首先,我们将创建一个字符串,它包含文件中存储的所有数字,且没有任何空
格:
pi_string.py
filename = 'pi_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
❶ pi_string = ''
❷ for line in lines:
pi_string += line.rstrip() ❸ print(pi_string)
print(len(pi_string))
就像前一个示例一样,我们首先打开文件,并将其中的所有行都存储在一个列表中。在❶处,我们创建了一个变量——pi_string ,用于存储圆周率的值。接下来,我们使用
一个循环将各行都加入pi_string ,并删除每行末尾的换行符(见❷)。在❸处,我们打印这个字符串及其长度: