1. 文件读写
-
读文件
Python中读取一个文件使用的方法是open()。
尝试打开一个文件:
-
创建一个test.txt文件
-
写入一些内容
3.1415926535 8979323846 2643383279 5028841971复制代码
-
新建file_reader.py文件,写入一下代码:
with open('test.txt') as file_object: contents = file_object.read() print(contents)复制代码
-
在终端执行
python3 file_reader.py
结果:
-
如果读取的文件是二进制文件,比如图片,视频则需要用
rb
模式:with open('test.png', 'rb') as file_object:复制代码
解释:
-
with关键字,可以让Python在不需要访问文件后将其关闭。这样我们就不用手动的调用
close()
方法去关闭文件了。 -
open()方法中如果只传入文件的名字,那么Python会在当期目录下进行查找。
-
read()方法会一次性读取文件全部内容,对待特别大的文件,可以使用
read(size)
,size参数表示从文件中读取的字节数。 -
open方法的mode参数默认是r,也就是说如果不传mode参数那么文件会以文本模式打开并读取。
-
readlines方法可以读取文件全部内容,并按行返回一个列表,注意换行符。
-
readline只读取一行
with open('test.txt') as file_object: contentList = file_object.readlines() print(contentList) # ['3.1415926535\n', ' 8979323846\n', ' 2643383279\n', ' 5028841971']复制代码
几种常见的open函数mode参数用法:
字符 含义 r 只读,指针在文件开头 rb 二进制只读,指针在文件开头 r+ 读写,指针位置根据读写的顺序决定 rb+ 二进制读写,指针位置根据读写的顺序决定 w 只写,如果文件不存在则创建文件,存在则覆盖文件 wb 二进制只写,如果文件不存在则创建文件,存在则覆盖文件 w+ 读写,如果文件不存在则创建文件,存在则覆盖文件 wb+ 二进制读写,如果文件不存在则创建文件,存在则覆盖文件 a 追加,如果文件不存在则创建文件,存在则在文件的末尾添加新内容,指针在文件末尾 ab 二进制追加,如果文件不存在则创建文件,存在则在文件的末尾添加新内容,指针在文件末尾 a+ 可以读可以追加,如果文件不存在则创建文件,存在则在文件的末尾添加新内容,指针在文件末尾 ab+ 二进制可以读可以追加,如果文件不存在则创建文件,存在则在文件的末尾添加新内容,指针在文件末尾 -
-
写文件
写文件分为两种,一种是直接覆盖原有内容,一种是在原有内容基础上添加新内容。它们对应的两种模式是
- w
with open('test.txt', 'w') as file_object: file_object.write('测试')复制代码
test.txt文件内容就被覆盖了
-
a
with open('test.txt', 'a') as file_object: file_object.write('随便写点什么')复制代码
新添加的内容就会放在test.txt原有内容的后面:
既读文件又写文件
r+
这里有点混乱,它和读写顺序有关还有指针的位置有关:
- 先读后写
# test.txttest# file_reader.pywith open('test.txt', 'r+') as file_object: contents = file_object.read() print(contents) file_object.write('Say something\n')复制代码
运行结果:
test.txt 文件:
先读后写,写入的内容会放在原有内容的末尾,读到的内容为文件原始内容。
- 先写后读
# test.txttest# file_reader.pywith open('test.txt', 'r+') as file_object: file_object.write('Say something\n') contents = file_object.read() print(contents)复制代码
运行结果:
test.txt文件:
可以看到之前的这一行被覆盖了。而且打印出读取到的文件内容是空。
这就牵扯到了指针问题,也就是输入的时候的闪动的光标,先写后读会覆盖原先位置上的内容,然后指针会跑到最后,读文件的时候从指针位置开始读,那么指针后面没有内容了所以是空,如果把test.txt文件写成这样,就会出现这样的结果:
# test.txtaaaaaaaaaaaabbbbbbbbbbbbccccccccccccddddddddddddeeeeeeeeeeee# file_reader.pywith open('test.txt', 'r+') as file_object: file_object.write('xxx') contents = file_object.read() print(contents)复制代码
结果:
test.txt 文件
看到没有,打印出来的结果中被a的那一行少3个,正是被write中的三个xxx覆盖了。打印出来的内容也是从覆盖完后的指针位置一直到结尾
如果想要获取完整内容,那么就要用到seek()方法,将指针移到开始的位置。
with open('test.txt', 'r+') as file_object: file_object.write('xxx') file_object.seek(0) # 新增 contents = file_object.read() print(contents)复制代码
结果
-
writelines
用write写入内容的时候,只能写入字符串,如果我们需要写入列表,那么就要用到writelines方法:
with open('./a.txt', 'w', encoding='utf-8') as file: file.writelines(['1', '2', '3', '4'])复制代码
结果:
- w
2. 异常
即使语句或表达式在语法上是正确的,但在尝试执行时,它仍可能会引发错误。 在执行时检测到的错误被称为异常
在Python中使用try-except代码块处理异常。
异常的类型可以参考(错误和异常)[]
# 只做除法的计算器print('Enter q to quit.')while True: firsr_number = input('\nFirst number: ') if(firsr_number) == 'q': break second_number = input('\nSecondt number: ') if(second_number) == 'q': break answer = int(firsr_number) / int(second_number) print(answer)复制代码
结果:
正常是没问题的,但是一旦用户输入第二个数字为0的时候,就会异常:
这时候我们就可以使用try-except代码块处理:
print('Enter q to quit.')while True: firsr_number = input('\nFirst number: ') if(firsr_number) == 'q': break second_number = input('\nSecondt number: ') if(second_number) == 'q': break try: answer = int(firsr_number) / int(second_number) except ZeroDivisionError: print("You can't divide by zore!") else: print(answer)复制代码
结果:
程序没有将traceback展示给用户,而是一句友好的提示。
还是用了else代码块,一般都是将有可能引发异常的代码放在try-except代码块中,依赖于try代码块成功执行的代码放在else代码块中。
- 抛出错误
通过raise语句可以抛出一个错误
age = 0if age < 1: raise Exception('Invalid age', age)复制代码
- pass语句
pass语句什么也不做,比如有一个异常,我捕获到了但是我什么也不想做,那么就可以使用pass
try: with open('password.txt') as file_object: contents = file_object.read() print(contents)except FileNotFoundError: pass复制代码
这样就算找不到password.txt文件,那么也不会报错。