文件和异常

文件和异常,第1张

文件和异常

文章目录
  • 文件和异常
    • 从文件中读取数据
      • 读取整个文件
      • 文件路径
      • 逐行读取
      • 创建一个包含文件各行内容的列表
      • 使用文件的内容
      • 圆周率值中包含你的生日吗
    • 写入文件


至此,你掌握了编写组织有序、易于使用的程序所需的基本技能,该考虑让程序目标更明确、用途更大了。


在本章中,你将学习处理文件,让程序能够快速地分析大量数据;你将学习错误处理,避免程序在面对意外情形时崩溃;你将学习异常,它们时 python 创建的特殊对象,用于管理程序运行时出现的错误;你还将学习模块 json,它让你能够保存用户数据,以免在程序停止运行后丢失。


从文件中读取数据 读取整个文件

要读取文件,需要一个包含几行文本的文件。


下面首先创建一个文件,它包含精确到小数点后30位的圆周率值,且在小数点后每10位处换行:

3.1415926535
  8979323846
  2643383279

下面的程序打开并读取这个文件,再将其内容显示到屏幕上:

with open('pi_digits.txt') as file_object:
	contents = file_object.read()
print(contents)

在这个程序中,第一行代码做了大量的工作。


我们先来看看函数 open()。


要以任何方式使用文件,哪怕仅仅是打印其内容,都得先打开文件,才能访问它。


函数 open() 接受一个参数:要打开的文件的名称。


python 在当前执行的文件所在的目录中查找指定的文件 pi_digits.txt。


函数 open() 返回一个表示文件的对象。


在这里,open(‘pi_digits.txt’) 返回一个表示文件 pi_digits.txt 的对象,python 将该对象赋给 file_object 供以后使用。



关键字 with 在不再需要访问文件后将其关闭。


在这个程序中,注意到我们调用了 open(),但没有调用 close()。


也可以调用 open() 和 close() 来打开和关闭文件,但这样做时,如果程序存在 bug 导致 close() 未执行,文件将不会关闭。


这看似微不足道,但未妥善关闭文件可能导致数据丢失或受损。


如果在程序中过早调用 close(),你会发现需要使用文件时它已经关闭(无法访问),这会导致更多的错误。


并非在任何情况下都唔能够轻松确定关闭文件的恰当时机,但通过使用前面所示的结构,可让 python 去确定:你只管打开文件,并在需要时使用它,python 自会在合适的时候自动将其关闭。



有了表示 pi_digits.txt 的文件对象后,使用方法 read() 读取这个文件的全部内容,并将其作为一个长长的字符串赋给变量 contents。


这样,通过打印 contents 的值,就可将这个文本文件的全部内容显示出来。


文件路径

将类似于 pi_digits.txt 的简单文件名传递给函数 open() 时,python 将在当前执行的文件(即 .py 程序文件)所在的目录中查找。



根据你组织文件的方式,有时可能要打开不在程序文件所属目录中的文件。


例如,你可能将程序文件存储在了文件夹 python_work 中,而该文件夹中有一个名为 text_files 的文件夹用于存储程序文件 *** 作的文本文件。


虽然 text_files 包含在文件夹 python_work 中,但仅向 open() 传递位于前者的文件名称也不可行,因为 python 只在文件夹 python_work 中查找,而不会在其子文件夹 text_files 中查找。


要让 python 打开不与程序文件位于同一目录中的文件,需要提供文件路径,让 python 到系统的特定位置去查找。



由于文件及 text_files 位于文件夹 python_work 中,可以使用相对文件路径来打开其中的文件。


相对路径让 python 到指定的位置去查找,而该位置时相对于当前运行的程序所在目录的。


例如:

with open('text_files/filename.txt') as file_object:

这行代码让 python 到文件夹 python_work 下的文件夹 text_files 中去查找指定的 .txt 文件。


注意显示文件路径时,Windows 系统使用反斜杠(\)而不是斜杠(/),但在代码中依然可以使用斜杠。


还可以将文件在计算机中的准确位置告诉 python,这样就不用关心当前运行的程序存储在什么地方了。


这称为绝对文件路径。


在相对路径行不通时,可使用绝对路径。


例如,如果 text_files 并不在文件夹 python_work 中,而在文件夹 other_files 中,则向 open() 传递路径 ’text_files/filename.txt’行不通,因为 python 只在文件夹 python_work 中查找该位置。


为明确指出 python 到哪里去查找,需要提供完整的路径。



绝对路径通常比相对路径长,因此将其赋给一个变量,再将变量传递给 open() 会有所帮助:

file_path = 'home/ehmatthes/other_files/text_files/filename.txt'
with open(file_path) as file_object:

通过使用绝对路径,可读取系统中任何地方的文件。


就目前而言,最简单的做法是,要么将数据文件存储在程序文件所在的目录,要么将其存储在程序文件所在目录下的一个文件夹(如 text_files)中。


注意 如果在文件路径中直接使用反斜杠,将发生错误,因为反斜杠用于对字符串中的字符进行转义。


例如,对于路径“C:\path\to\file.txt”,其中的 \t 将被解读为制表符。


如果一定要使用反斜杠,可对路径中的每个反斜杠都进行转义,如“C:\path\to\file.txt”。


逐行读取

读取文件时,常常需要检查其中的每一行:可能要在文件中查找特定的信息,或者要以某种方式修改文件中的文本。


例如,你可能要遍历一个包含天气数据的文件,并使用天气描述中包含 sunny 字样的行。


在新闻报道中,你可能会查找包含标签的行,并按特定的格式设置它。



要用每次一行的方式检查文件,可对文件对象使用 for 循环:

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.strip())
3.1415926535  
  8979323846
  2643383279
创建一个包含文件各行内容的列表

使用关键字 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.strip())
3.1415926535  
  8979323846
  2643383279

使用方法 readlines() 从文件中读取每一行,并将其存储在一个列表中。


接下来,该列表被赋给变量 lines。


在 with 代码块外,依然可以使用这个变量。


接着使用一个简单的 for 循环来打印 lines 中的各行。


因为列表 lines 的每个元素都对应于文件中的一行,所以输出与文件内荣完全一致。


使用文件的内容

将文件读取到内存中后,就能一任何方式使用这些数据了。


下面以简单的方式使用圆周率的值。


首先,创建一个字符串,它包含文件中存储的所有数字,且没有任何空格:

>>> filename = 'pi_digits.txt'
>>> with open(filename) as file_object:
>>> 	lines = file_object.readlines()
>>> pi_string = ''
>>> for line in lines:
>>> 	pi_string += line.strip()
>>> print(pi_string)
>>> print(len(pi_string))
3.141592653589793238462643383279
32

像前一个示例一样,首先打开文件,并将其中所有的行都存储在一个列表中。


本例中创建了一个变量 pi_string,用于指向圆周率的值。


接下来,使用一个循环将各行加入 pi_string,并删除每行末尾的换行符。


并打印这个字符串及其长度。


注意 读取文本文件时,python 将其中的所有文本都解读为字符串。


如果读取的是数,并要将其作为数值使用,就必须使用函数 int() 将其转换为整数或使用函数 float() 将其转换为浮点数。


圆周率值中包含你的生日吗

我一直想知道自己的生日是否包含在圆周率值中。


下面来扩展刚才编写的程序,以确定某个人的生日是否包含在圆周率值得前 1_000_000 位中。


为此,可将生日表示为一个由数字组成的字符串,再检查这个字符串是否包含在 pi_string 中:

>>> filename = 'pi_digits.txt'
>>> with open(filename) as file_object:
>>> 	lines = file_object.readlines()
>>> pi_string = ''
>>> for line in lines:
>>> 	pi_string += line.strip()
>>> birthday = input("Enter your birthday, in the form mmddyy: ")
>>> if birthday in pi_string:
>>> 	print("Your birthday appears in the first million digits of pi!")
>>> else:
>>> 	print("Your birthday does not appear in the first million digits of pi.")
Enter your birthday, in the form mmddyy: 120372
Your birthday appears in the first million digits of pi!

写入文件

保存数据的最简单的方式之一是将其写入文件中。


通过将输出写入文件

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/568770.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-09
下一篇 2022-04-09

发表评论

登录后才能评论

评论列表(0条)

保存