CSDN 课程推荐:《8小时Python零基础轻松入门》,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员;已出版《跟老齐学Python:轻松入门》《跟老齐学Python:Django实战》、《跟老齐学Python:数据分析》和《Python大学实用教程》畅销图书。


Python3 基础学习笔记第九章【文件和异常】

目录

  • 【9.1】从文件中读取数据
    • 【9.1.1】读取整个文件
    • 【9.1.2】文件路径
    • 【9.1.3】逐行读取
    • 【9.1.4】创建一个包含文件各行内容的列表
    • 【9.1.5】使用文件的内容
  • 【9.2】写入文件
  • 【9.3】使用 try-except 代码块处理异常
  • 【9.4】储存数据
    • 【9.4.1】使用 json.dump() 和 json.load()
    • 【9.4.2】重构

【9.1】从文件中读取数据

【9.1.1】读取整个文件

有一个文件,包含精确到小数点后30位的圆周率值,且在小数点后每10位处都换行:

Circumference rate.txt
-----------------------
3.141592653589793238462643383279

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

#file_reader.pywith open('Circumference rate.txt') as file_object:contents = file_object.read()print(contents)
#file_reader2.pycontents = open ('Circumference rate.txt')
print(contents.read())
contents.close()

函数open()接受一个参数:要打开的文件的名称,Python在当前执行的文件所在的目录中查找指定的文件;关键字with在不再需要访问文件后将其关闭;也可以调用open()和close()来打开和关闭文件,如果使用这种方法,当程序存在bug时,close()语句未执行,文件将不会被关闭;方法read()将读取这个文件的全部内容,并将其作为一个长长的字符串储存在变量contents中,通过打印contents的值,就可以将这个文本文件的全部内容打印出来:

3.141592653589793238462643383279

输出结果末尾有一空行,这是因为read()到达末尾时返回一个空字符串,而将这个空字符串显示出来就是一个空行,如果要删除末尾的空行,可在print语句中使用rstrip():

#file_reader.pywith open('Circumference rate.txt') as file_object:contents = file_object.read()print(contents.rstrip())

输出结果如下:

3.141592653589793238462643383279

【9.1.2】文件路径

相对文件路径:假定程序文件位于python_work文件夹中,程序文件操作的文本文件位于python_work文件夹的子文件夹text_files中,此时可以使用相对文件路径来打开该文本文件,相对文件路径让Python到指定的位置去查找,而该位置是相对于当前运行的程序所在目录的

在Linux和OS X中,相对路径类似于如下:

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

在Windows系统中,文件路径中使用反斜杠(\)而不是斜杠(/):

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

绝对文件路径:不用关心当前运行的程序储存在什么地方,直接将文件在计算机中的准确位置告诉Python,这称为绝对文件路径,绝对路径通常比相对路径更长,因此将其储存在一个变量中,再将变量传递给open()会有所帮助

在Linux和OS X中,绝对路径类似于如下:

file_path = '/home/ehmatthes/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:

【9.1.3】逐行读取

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

#file_reader.pyfilename = 'Circumference rate.txt'
with open(filename) as file_object:for line in file_object:print(line)

在文件中每行的末尾都有一个看不见的换行符,而print语句也会加上一个换行符,因此每行末尾都有两个换行符:一个来自文件,一个来自print语句,输出结果如下:

3.141592653589793238462643383279

要消除这些多余的空白行,可以使用rstrip():

#file_reader.pyfilename = 'Circumference rate.txt'
with open(filename) as file_object:for line in file_object:print(line.rstrip())

输出结果如下:

3.141592653589793238462643383279

【9.1.4】创建一个包含文件各行内容的列表

使用关键字with时,open()返回的文件对象只在with代码块内可用,如果要在with代码块外访问文件的内容,可在with代码块内将文件的各行储存在一个列表当中,并在with代码块外使用该列表:

#file_reader.pyfilename = 'Circumference rate.txt'
with open(filename) as file_object:lines = file_object.readlines()for line in lines:print(line.rstrip())

输出结果与文件内容完全一致

【9.1.5】使用文件的内容

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

#pi_string.pyfilename = 'Circumference rate.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))

打印该字符串以及其长度:

3.1415926535  8979323846  2643383279
36

由于原文件每行左边都有空格,我们可以使用strip()而不是rstrip()来删除它:

#pi_string.pyfilename = 'Circumference rate.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

Python中有三个去除头尾字符、空白符的函数,它们依次为:
strip:用来去除头尾字符、空白符(包括\n、\r、\t、’ ‘,即:换行、回车、制表符、空格)
lstrip:用来去除开头字符、空白符(包括\n、\r、\t、’ ‘,即:换行、回车、制表符、空格)
rstrip:用来去除结尾字符、空白符(包括\n、\r、\t、’ ‘,即:换行、回车、制表符、空格)
注意:这些函数都只会删除头和尾的字符,中间的不会删除。
用法分别为:
string.strip([chars])
string.lstrip([chars])
string.rstrip([chars])
参数chars是可选的,当chars为空,默认删除string头尾的空白符(包括\n、\r、\t、’ ')
当chars不为空时,函数会被chars解成一个个的字符,然后将这些字符去掉
它返回的是去除头尾字符(或空白符)的string副本,string本身不会发生改变

【9.2】写入文件

将一条简单的消息储存到文件中:

#write_message.pyfilename = 'programming.txt'
with open(filename,'w') as file_object:file_object.write("I love programming!")

调用open()时提供了两个实参,第一个实参也是要打开文件的名称,第二个实参(‘w’)告诉Python,我们要以写入模式打开这个文件,打开文件时,可指定读取模式(‘r’)、写入模式(‘w’)、附加模式(‘a’)或者让我们能够读取和写入文件的模式(‘r+’),如果省略模式实参,则默认以只读模式打开文件

附表:Python读写文件各种模式区别
模式 可做操作 若文件不存在 是否覆盖
r 打开一个文件用于只读 报错 -
rb 以二进制格式打开一个文件用于只读 报错 -
r+ 打开一个文件用于读和写 报错 否,追加写
rb+ 以二进制格式打开一个文件用于读和写 报错 否,追加写
w 打开一个文件用于只写 创建
wb 以二进制格式打开一个文件只用于只写 创建
w+ 打开一个文件用于读和写 创建
wb+ 以二进制格式打开一个文件用于读和写 创建
a 打开一个文件用于追加 创建 否,追加写
ab 以二进制格式打开一个文件用于追加 创建 否,追加写
a+ 打开一个文件用于读和写 创建 否,追加写
ab+ 以二进制格式打开一个文件用于追加 创建 否,追加写

【9.3】使用 try-except 代码块处理异常

当我们尝试将一个数字除以0时,会发生ZeroDivisionError异常:

>>> print(5/0)
Traceback (most recent call last):File "<pyshell#0>", line 1, in <module>print(5/0)
ZeroDivisionError: division by zero

此时我们可以编写一个try-except代码块来处理该异常:

try:print(5/0)
except ZeroDivisionError:print("You can't divide by zero!")

当我们运行该程序时,会出现提示:

You can't divide by zero!

在try-except代码块中加入else,编写一个只执行除法运算的简单计算器:

print("Give me two numbers,and I'll divide them.")
print("Enter 'q' to quit.")while True:first_number = input("\nFirst number:")if first_number == 'q':breaksecond_number = input("\nSecond number:")if second_number == 'q':breaktry:answer = int(first_number)/int(second_number)except ZeroDivisionError:print("You can't divide by 0!")else:print(answer)

运行程序:

Give me two numbers,and I'll divide them.
Enter 'q' to quit.First number:45Second number:0
You can't divide by 0!First number:36Second number:8
4.5First number:q

若不加入try-except代码块,我们在输入0时,程序就会出现异常而崩溃,而try-except代码块很好的解决了这种问题,而且还起到了提示的作用,同样的,try-except代码块也可以处理其他异常,如FileNotFoundError等

【9.4】储存数据

【9.4.1】使用 json.dump() 和 json.load()

模块json能够将简单的Python数据结构转储到文件中,并在程序再次运行时加载该文件中的数据;编写一个储存一组数字的简短程序,再编写一个将这些数字读取到内存中的程序,第一个程序将使用 json.dump()来储存这组数据,而第二个程序将使用 json.load()。函数 json.dump()接受两个实参:要储存的数据以及可用于储存数据的文件对象:

#number_writer.pyimport jsonnumbers = [2,3,5,7,11,13]filename = 'numbers.json'
with open(filename,'w') as f_obj:json.dump(numbers,f_obj)

先导入模块json,再创建一个数字列表, 通常用文件扩展名.json来指出文件储存的数据为JSON格式,然后以写入模式打开该文件,使用函数json.dump()将数字列表储存到文件numbers.json中,打开该文件,数据的储存格式与Python一样:

[2, 3, 5, 7, 11, 13]

再编写一个程序,使用json.load()将这个列表读取到内存中:

#number_reader.pyimport jsonfilename = 'numbers.json'
with open(filename) as f_obj:numbers = json.load(f_obj)
print(numbers)

输出结果与number_writer.py中创建的数字列表相同:

[2, 3, 5, 7, 11, 13]

进阶:在同一个程序中使用 json.dump() 和 json.load():创建文件username.json储存用户名,从该文件中获取用户名,如果这个文件不存在,就在except代码块中提示用户输入用户名,并将其储存在username.json中:

#remember_me.pyimport json#如果以前储存了用户名,就加载它
#否则就提示用户输入用户名并储存它
filename = 'numbers.json'
try:with open(filename) as f_obj:username = json.load(f_obj)
except FileNotFoundError:username = input("What's your name?")with open(filename,'w') as f_obj:json.dump(username,f_obj)print("We'll remember you when you come back, " + username + "!")
else:        print("Welcome back, " + username + "!")

以前没有储存用户名,第一次运行程序:

What's your name?TRHX
We'll remember you when you come back, TRHX!

再次运行程序:

Welcome back, TRHX!

【9.4.2】重构

代码能够正确运行,但可以做进一步的改进——将代码划分为一系列完成具体工作的函数,这样的过程称为重构,重构让代码更清晰、更易于理解、更容易扩展
重构remember_me.py,将大部分逻辑放到一个或者多个函数中:

#remember_me.pyimport jsondef greet_user():#问候用户,并指出其名字filename = 'numbers.json'try:with open(filename) as f_obj:username = json.load(f_obj)except FileNotFoundError:username = input("What's your name?")with open(filename,'w') as f_obj:json.dump(username,f_obj)print("We'll remember you when you come back, " + username + "!")else:        print("Welcome back, " + username + "!")greet_user()

重构greet_user(),让它不执行这么多任务——将获取储存的用户名的代码移到另一个函数中:

#remember_me.pyimport jsondef get_stored_username():#如果储存了用户名,就获取它filename = 'numbers.json'try:with open(filename) as f_obj:username = json.load(f_obj)except FileNotFoundError:return Noneelse:return usernamedef greet_user():#问候用户,并指出其名字username = get_stored_username()if username:print("Welcome back, " + username + "!")else:username = input("What's your name?")filename = 'username.json'with open(filename,'w') as f_obj:json.dump(username,f_obj)print("We'll remember you when you come back, " + username + "!")     greet_user()

将greet_user()中的另一个代码块提取出来:将没有储存用户名时提示用户输入的代码放在一个独立的函数中:

#remember_me.pyimport jsondef get_stored_username():#如果储存了用户名,就获取它filename = 'numbers.json'try:with open(filename) as f_obj:username = json.load(f_obj)except FileNotFoundError:return Noneelse:return usernamedef get_new_username():#提示输入用户名username = input("What's your name?")filename = 'username.json'with open(filename,'w') as f_obj:json.dump(username,f_obj)return usernamedef greet_user():#问候用户,并指出其名字username = get_stored_username()if username:print("Welcome back, " + username + "!")else:username = get_new_username()print("We'll remember you when you come back, " + username + "!")     greet_user()

最终版本实现了每个函数只负责单一而清晰的任务,我们在编写程序时也要像这样,要写出清晰而易于维护和扩展的代码

Python3 基础学习笔记 C09【文件和异常】相关推荐

  1. Python基础学习笔记-8.文件、异常和模块

    8.文件.异常和模块 8.1.文件的读写 8.1.1.文件的打开 实际应用中,我们绝大多数的数据都是通过文件的交互完成的 首先,来看文件打开的通用格式 with open("文件路径&quo ...

  2. Python3 基础学习笔记 C08 【类】

    CSDN 课程推荐:<8小时Python零基础轻松入门>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python:轻松入门& ...

  3. Python3 基础学习笔记 C07【函数】

    CSDN 课程推荐:<8小时Python零基础轻松入门>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python:轻松入门& ...

  4. Python3 基础学习笔记 C06【用户输入和 while 循环】

    CSDN 课程推荐:<8小时Python零基础轻松入门>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python:轻松入门& ...

  5. Python3 基础学习笔记 C05【字典】

    CSDN 课程推荐:<8小时Python零基础轻松入门>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python:轻松入门& ...

  6. Python3 基础学习笔记 C04【if 语句】

    CSDN 课程推荐:<8小时Python零基础轻松入门>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python:轻松入门& ...

  7. Python3 基础学习笔记 C03【操作列表】

    CSDN 课程推荐:<8小时Python零基础轻松入门>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python:轻松入门& ...

  8. Python3 基础学习笔记 C02【列表】

    CSDN 课程推荐:<8小时Python零基础轻松入门>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python:轻松入门& ...

  9. Python3 基础学习笔记 C01【变量和简单数据类型】

    CSDN 课程推荐:<8小时Python零基础轻松入门>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python:轻松入门& ...

最新文章

  1. CornerNet的配置、训练与测试
  2. 【数据结构】顺序栈的实现(C语言)
  3. 我是如何一步步让公司的MySQL支撑亿级流量的?
  4. python网页爬虫-python网页爬虫浅析
  5. Android系统中的任意文件读写方法
  6. python 合并 循环list_阿里巴巴鼎力推荐,Python入门至精通,24招加速你的Python
  7. VS2008 Web Application和Web Site的区别_转载
  8. 合并 多个dataframe_什么是Pandas的DataFrame?
  9. 2020年灵活用工行业研究报告
  10. 因DataValueField设置不当引起的DropDownList的SelectedItem的取不到所选值的问题
  11. python能做什么毕业设计-有没有适合python做的毕设题目,现在不知道做什么了?...
  12. Html 垂直滚动条 定位到 指定位置
  13. docker-compose部署nacos 集群超过2个容器的问题
  14. 009-2010网络最热的 嵌入式学习|ARM|Linux|wince|ucos|经典资料与实例分析
  15. a form 出口享惠情况_关于“出口享惠情况”如何填报?
  16. 四六级考试中的计算机类文章,四六级英语考试进入机考时代
  17. 每日三思:优化微信小程序中倒计时占内存较大(19-0612-1917)
  18. android 应用图标替换后手机安装还显示旧的图标或者显示android小人人
  19. 易基因|RNA m7G甲基化测序(m7G-MeRIP-seq)
  20. 58同城南京品牌公馆数据爬取

热门文章

  1. Date Picker控件:
  2. dd , /dev/zero和/dev/null
  3. matlab win10 gpu加速,win10的Edge浏览器设置GPU硬件加速,大幅度提升浏览器性能
  4. Java如何随机出石头剪刀布_JAVA编程实现石头剪刀布
  5. frontcon函数用不了_C++复制构造函数与析构函数
  6. python gui 自动化_python GUI测试自动化
  7. RT-Thread 简介及架构
  8. linux 文件重命名_如何在 Linux 上重命名一组文件 | Linux 中国
  9. mysql 表上限_mysql 数据库表的上限
  10. 安卓工控主板运行时会自动重启_工控主板在工业自动化中的应用