文件读写
文件处理是很常见的IO操作。通常我们使用 input 从控制台读取输入,然后将用户输入的内容输出到控制台。使用文件操作,我们就可以将用户的输入写入文件,或者将不同数据源中的数据移植到文件中。Python为创建文件、读取文件、更新文件、和删除文件都提供了相对应的函数。
操作文件最核心的函数是open()函数,此函数需要两个参数:filename, mode。filename对应你要操作的文件名,mode对应你要对文件进行的操作,以下是不同mode对应的具体意义:
“r” | 读模式 | 默认操作。打开文件, 并读取其内容, 如果文件不存在就会返回错误。 |
“a” | 追加模式 | 添加内容,如果文件不存在,会自动创建其文件。 |
“w” | 写模式 | 打开文件,并写入内容,如果文件不存在,就会自动创建。 |
“x” | 创模式 | 创建特定的文件,如果文件已存在,就会返回错误。 |
此外,你还可以定义是要以什么形式来处理文件:
“t” | 文本 | 文本模式 (默认) |
“b” | 二进制 | 二进制模式(比如图片) |
打开文件
假设我们创建了文件file.txt,此文件和Python文件位于相同的文件夹:
Hello! Welcome to file.txt
This file is for testing purposes.
Good Luck!
若要打开文件,我们直接使用open()函数,并返回一个文件实例,此实例有一个read()方法供我们使用,可以读取文件的内容:
f = open("file.txt")
print(f.read())
以下代码实现了相同的功能,”r”代表读模式,”t”代表文本模式,他们都是默认值,你不需要定义他们。(注意:要保证文件存在,不然读模式会返回错误)
f = open("file.txt", "rt")
print(f.read())
读取文件
读取文件的方式有很多种,read()函数默认情况下会读取整个文件,如果我们只想读取特定字符数,可以给read添加参数来限定字符数。如果想要逐行读取文件,可以使用readline()函数。
f = open("file.txt", "r")
print(f.read(5)) # Return the first 5 characters of the file
print(f.readline()) # Read one line of the file
print(f.readline()) # Read the second line
如果迭代文件,文件也会一行一行地被读取:
f = open("file.txt", "r")
for x in f:
print(x)
每次操作完文件后,需要使用close()函数,将文件关闭:
f = open("file.txt", "r")
print(f.readline())
f.close()
写和创建文件
如果想将内容写入文件,我们必须在open()函数中添加”a”或”w”参数。”a”是追加模式,会在文件已存内容后面添加新内容。”w”是写模式,新内容会被旧内容覆盖。
f = open("file.txt", "a")
f.write("Now the file has more content!") # append the content to the file
f.close()
# open and read the file after the appending:
f = open("file.txt", "r")
print(f.read())
f.close()
f = open("file.txt", "w")
f.write("Woops! I have deleted the content!") # overwrite the content
f.close()
# open and read the file after the appending:
f = open("file.txt", "r")
print(f.read())
如果想要创建一个文件,在open函数中使用参数”x”, “a”或”w”都可以。”x”能创建一个文件,但是如果文件已存在,就会返回错误。如果指定的文件不存在,”a”和”w”模式都会自动创建一个新文件。
f = open("file2.txt", "x") # a new empty file is created.
f = open("file3.txt", "w") # create a new file if it does not exist
删除文件
如果要删除一个文件,我们需要调用os模块,然后使用os.remove()函数:
import os
os.remove("file.txt")
为了避免出现错误,在删除一个文件前最好检查一下此文件是否存在:
import os
if os.path.exists("file.txt"):
os.remove("file.txt")
else:
print("The file does not exist")
如果要删除整个文件夹,使用os.rmdir()函数即可:
import os
os.rmdir("newfolder")
异常处理
有时候我们的程序会出现异常,但我们又不想这些代码影响到软件的正常运行,这时候我们就要使用Python中的try,来处理有可能出现的异常:
try:
print(x)
except:
print("An exception occurred")
上面代码中因为x没有定义,所以会出现错误,当错误出现时,except中的代码就会被运行。如果不使用try,程序就会崩溃,并出现错误。
如果我们希望对特定的异常进行特定的处理,我们可以使用多个except语句:
try:
print(x)
except NameError:
print("Variable x is not defined")
except:
print("Something else went wrong")
除了NameError之外的异常出现的话,最后的except会被运行。如果想对无异常的情况进行特定处理,我们可以使用else关键词:
try:
print("Hello")
except:
print("Something went wrong")
else:
print("Nothing went wrong")
Python也提供了很方便的finally,定义finally代码块后,不管try中的代码会不会引起异常,finally中的代码都会被执行:
try:
print(x)
except:
print("Something went wrong")
finally:
print("The 'try except' is finished")
在处理文件的时候,我们经常会在finally中关闭文件,来保证程序的正常运行:
f = open("file.txt")
try:
f.write("Awesome")
except:
print("Something went wrong when writing to the file")
finally:
f.close()
with语句
with语句适合用于对资源进行访问的场合,确保运行过程中不管是否有异常,都会执行必要的“清理”操作,释放被操作的资源,比如文件的自动关闭或者线程中锁的自动获取和释放等。
在我们处理文件时,通常要编写以下的代码来保证程序正常运行:
try:
file = open("file.txt")
content = file.read()
except:
print("Error")
finally:
file.close()
虽然以上代码运行正常,可是比较冗长。使用with的话,不仅使代码更加简洁,还能处理上下文环境产生的异常:
with open("file.txt", "w") as file:
file.write("Hi there!")
with的工作原理我这里不展开讲,简单来说,紧跟在with后面的语句被求值后,返回对象内置的__enter__()函数会被调用,这个方法的返回值会被赋值给as后面的变量。当with后面的代码全部被执行完之后,将会调用返回对象的__exit__()方法。
实际上,在with后面的代码抛出异常后,__exit__()函数会被执行。一般清理资源,关闭文件等操作,都会被放在exit()方法中。总之,with…as表达式简化了每次都要写finally的繁琐工作,极大提升了代码的优雅性。我们甚至还能在with后面使用多项as:
with open("file.txt") as f1, open("file2.txt") as f2:
# do anything
实践练习
请创建一个程序可以根据用户的输入对文件进行读或者写操作,不管读还是写,都需要用户先手动输入文件名。在读操作中,如果文件读取成功,需要打印文件内容。在写操作中,使用追写模式添加任意内容后,打印修改后的文件内容即可。(注意:要对可能出现的异常进行处理,并在最后将文件关闭)
def file_operator(file_name, mode):
try:
if mode == "r":
with open(file_name, "r") as file:
print(file.read())
elif mode == "w":
with open(file_name, "a") as file:
file.write("New Content")
file.close()
file = open(file_name, "r")
print(file.read())
except IOError:
print("Error")
def prompt():
message = "Please input the file name: "
file_name = input(message)
message = "Read or Write?(r, w) "
mode = input(message)
file_operator(file_name, mode)
prompt()