目录
9.2、从文件中读取数据
文本文件可存储的数据量多得难以置信:天气数据、交通数据、社会经济数据、文学作品等。每当需要分析或修改存储在文件中的信息时,读取文件都很有用,对数据分析应用程序来说尤其如此。例如,你可以编写一个这样的程序:读取一个文本文件的内容,重新设置这些数据的格式并将其写入文件,让浏览器能够显示这些内容。
9.2.1、读取整个文件
要读取文件,需要一个包含几行文本的文件。下面首先来创建一个文件,它包含精确到小数点后30位的圆周率值,且在小数点后每10位处都换行:
3.1415926535
8979323846
2643393279
下面的程序打开并读取这个文件,再将其内容显示到屏幕上:
with open('圆周率.txt') as file_object:
conts = file_object.read()
print(conts.rstrip())
运行结果:
3.1415926535
8979323846
2643393279
代码解析:
要以任何方式使用文件,哪怕仅仅是打印其中内容,都得先打开文件,这样才能访问它。
open()函数:接收一个参数:要打开的文件名称。
python在当前执行的文件所在的目录中查找指定的文件。
在示例中,当前运行的是Class_file.py,因此Python在这个文件所在的目录中查找‘圆周率.txt‘。
函数open()返回一个表示文件的对象。
open('圆周率.txt')返回一个表示文件'圆周率.txt'的对象;
将对象存储在conts变量中。
关键字with在不再需要访问文件后将其关闭。
在这个程序中,注意到我们调用了open(),但没有调用close();你也可以调用open()和close()来打开和关闭文件,但这样做时,如果程序存在bug,
导致close()语句未执行,文件将不会关闭。这看似微不足道,但未妥善地关闭文件可能会导致数据丢失或受损。如果在程序中过早地调用close(),
你会发现需要使用文件时它已关闭(无法访问),这会导致更多的错误。并非在任何情况下都能轻松确定关闭文件的恰当时机,但通过使用前面所示的结构,
可让Python去确定:你只管打开文件,并在需要时使用它,Python自会在合适的时候自动将其关闭。
9.2.2、文件路径
当你将类似'圆周率.txt'这样的简单文件名传递给函数open()时,
Python将在当前执行的文件(即.py程序文件)所在的目录中查找文件。
在.py文件的同级目录下添加一个test目录,将’圆周率.txt‘文件放在其中,
要想访问这个文件就需要给open()函数传递一个文件路径。
下面这行代码是让Python到文件夹test中查找指定的.txt文件。
注意:
在Windows系统中,在文件路径中使用反斜杠(\)而不是斜杠(/):
# 方式一:
with open('test\\圆周率.txt') as file:
# 方式二:
file_path = 'E:\\pythonProject\\Demo\\test\\圆周率.txt'
file_p = r'E:/pythonProject/Demo/test/圆周率.txt'
with open(file_path) as file_a:
con = file_a.read()
print(con)
注意 Windows系统有时能够正确地解读文件路径中的斜杠。如果你使用的是Windows系统,且结果不符合预期,请确保在文件路径中使用的是反斜杠。另外,由于反斜杠在Python中被视为转义标记,为在Windows中确保万无一失,应以原始字符串的方式指定路径,即在开头的单引号前加上r。
9.2.3、逐行读取
读取文件时,常常需要检查其中的每一行:你可能要在文件中查找特定的信息,或者要以某种方式修改文件中的文本。例如,你可能要遍历一个包含天气数据的文件,并使用天气描述中包含字样sunny的行。在新闻报道中,你可能会查找包含标签<headline>的行,并按特定的格式设置它。要以每次一行的方式检查文件,可对文件对象使用for循环:
f_path = r'E:\pythonProject\Demo\test\圆周率.txt'
with open(f_path) as file:
for line in file:
print(line)
运行结果:
3.1415926535
8979323846
2643393279
为什么会出现这些空白行呢?因为这个文件中,每行的末尾都有一个看不见的换行符,而print语句也会加上一个换行符,因此每行末尾都有两个换行符:一个来自文件,另一个来自print语句。要消除这些多余的空白行,可以在print中使用rstrip()函数
f_path = r'E:\pythonProject\Demo\test\圆周率.txt'
with open(f_path) as file:
for line in file:
print(line.rstrip())
输出结果:
3.1415926535
8979323846
2643393279
9.2.4、创建一个包含文件各行内容的列表
使用关键字with时,open()返回的文件对象只在with代码块内可用。如果要在with代码块外访问文件的内容,可在with代码块内将文件的各行存储在一个列表中,并在with代码块外使用该列表:你可以立即处理文件的各个部分,也可推迟到程序后面再处理。
f_path = r'E:\pythonProject\Demo\test\圆周率.txt'
with open(f_path) as file:
lines = file.readlines() # 1
for line in lines: # 2
print(line.rstrip())
代码解读:
❶处的方法readlines()从文件中读取每一行,并将其存储在一个列表中;接下来,该列表被存储到变量lines中;在with代码块外,我们依然可以使用这个变量。在❷处,我们使用一个简单的for循环来打印lines中的各行。由于列表lines的每个元素都对应于文件中的一行,因此输出与文件内容完全一致。
9.2.5、使用文件的内容
将文件读取到内存中后,就可以以任何方式使用这些数据了。下面以简单的方式使用圆周率的值。首先,我们将创建一个字符串,它包含文件中存储的所有数字,且没有任何空格:
f_path = r'E:\pythonProject\Demo\test\圆周率.txt'
with open(f_path) as fi_path:
lines = fi_path.readlines()
pi_string = '' # 1
for lin in lines: # 2
pi_string += lin.rstrip()
print('pi_string===>'+pi_string) # 3
print('字符串长度为:'+str(len(pi_string)))
代码解析:
首先打开文件,并将其中的所有行都存储在一个列表中。在❶处,我们创建了一个变量——pi_string,用于存储圆周率的值。接下来,我们使用一个循环将各行都加入pi_string,并删除每行末尾的换行符(见❷)。在❸处,我们打印这个字符串及其长度。
运行结果:
pi_string===>3.1415926535 8979323846 2643393279
字符串长度为:36
在变量pi_string存储的字符串中,包含原来位于每行左边的空格,为删除这些空格,可使用strip()而不是rstrip():
pi_string += lin.strip()
运行结果:
pi_string===>3.141592653589793238462643393279
字符串长度为:32
注意:
读取文本文件时,Python将其中的所有文本都解读为字符串。如果你读取的是数字,并要将其作为数值使用,就必须使用函数int()将其转换为整数,或使用函数float()将其转换为浮点数。
9.2.6、圆周率中是否包含用户的生日
下面来扩展刚才编写的程序,以确定某个人的生日是否包含在圆周率值的前1000000位中。为此,可将生日表示为一个由数字组成的字符串,再检查这个字符串是否包含在pi_string中。
f_path = r'E:\pythonProject\Demo\test\圆周率.txt'
with open(f_path) as fi_path:
lin = fi_path.readlines()
pi_string = ''
for line in lin:
pi_string+=line.strip()
birthday = input('输入你的生日:\n')
if birthday in pi_string:
print("你的生日在PI中")
else:
print("PI中不包含你的生日")
知识拓展:
可使用方法replace()将字符串中的特定单词都替换为另一个单词。下面是一个简单的示例,演示了如何将句子中的'like'替换为'非常喜欢'
msg = 'Hello world,I like java' print(msg.replace('like','非常喜欢'))
运行结果:
Hello world,I 非常喜欢 java