本文代码
地址github.com在Python中我们使用open
函数来读写文件,在使用open
函数时,我们可以通过函数的参数指定文件名、操作模式和字符编码等信息,然后对文件进行读写操作,这里所说的操作模式是指要打开什么样的文件(文本文件或二进制文件)以及做什么样的操作(读、写或追加),具体如下表所示
下面我们举例来看如何读写文件
# 第一个参数指定文件名,第二个参数指定操作模式,encoding参数指定文件编码,默认是utf-8编码
f = open("./data/filename.txt", "w", encoding="utf-8")
# 通过write写入内容
f.write("这是第1行文本n")
f.write("这是第2行文本n")
for i in range(3, 10):
f.write("这是第{}行文本n".format(i))
# 操作完文件之后要关闭文件
f.close()
f = open("./data/filename.txt", "r", encoding="utf-8")
# open返回的是可迭代对象,因而我们可以使用for循环遍历
for line in f:
print(line.strip())
# 操作完成之后要关闭文件
f.close()
这是第1行文本
这是第2行文本
这是第3行文本
这是第4行文本
这是第5行文本
这是第6行文本
这是第7行文本
这是第8行文本
这是第9行文本
# 指定b选项读取二进制文件
f = open("./data/test.jpg", "rb")
# 读取二进制文件内容
data = f.read()
f.close()
# 指定b选项写入二进制数据
f = open("./data/other.jpg", "wb")
# 将二进制数据写入文件
f.write(data)
f.close()
通常情况下我们会将open
函数放到with
上下文中,把open
放到with
上下文中最大的好处是我们不需要手动调用close
关闭文件,因为离开with
上下文之后会自动调用close
关闭文件
with open("./data/filename.txt", "r", encoding="utf-8") as f:
for line in f:
print(line.strip())
# 在此处,退出with上文之后将会自动关闭文件,我们不需要手动调用close关闭文件
这是第1行文本
这是第2行文本
这是第3行文本
这是第4行文本
这是第5行文本
这是第6行文本
这是第7行文本
这是第8行文本
这是第9行文本
即使语句或表达式在语法上正确,但在运行的时候它仍可能引发错误,我们把在运行时检测到的错误称为异常,如上面我们介绍文件操作时,如果我们打开一个不存在的文件将会引发异常,为了让代码具有健壮性和容错性,我们可以使用Python的异常机制对可能在运行时发生状况的代码进行适当的处理,当程序抛出异常时,Python按如下步骤处理异常
try
语句except
子句并完成try
语句的执行try
子句时发生了异常,则跳过该子句中剩余的部分. 如果发生的异常类型与except
后面的异常类型匹配,则执行except
子句except
后面跟的异常类型不匹配,则该异常是一个未处理的异常,程序将停止执行下面我们举例来看异常处理用法
# 捕获用户输入并将其转换为整数,可以试试输入整数和字符串,当输入数据无法转换为int时将抛出ValueError异常
# 如果不处理异常将导致程序终止,后续代码都不会执行
x = int(input("输入一个整数: "))
y = x * x
print("y = {}".format(y))
输入一个整数: asdf
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
in
1 # 捕获用户输入并将其转换为整数,可以试试输入整数和字符串,当输入数据无法转换为int时将抛出ValueError异常
2 # 如果不处理异常将导致程序终止,后续代码都不会执行
----> 3 x = int(input("输入一个整数: "))
4 y = x * x
5 print("y = {}".format(y))
ValueError: invalid literal for int() with base 10: 'asdf'
try:
# 捕获用户输入并将其转换为整数,可以试试输入整数和字符串,当输入数据无法转换为int时将抛出ValueError异常
x = int(input("输入一个整数: "))
y = x * x
print("y = {}".format(y))
except ValueError:
# 如果抛出了ValueError异常,那么在抛出异常后继续执行此处的逻辑,此处一般编写异常处理代码
print("输入异常,你输入的不是一个整数")
输入一个整数: asdf
输入异常,你输入的不是一个整数
try:
x = int(input("输入一个整数: "))
y = x * x
print("y = {}".format(y))
except ZeroDivisionError:
# 这里捕获的是ZeroDivisionError,而该程序抛出的是ValueError,异常类型不匹配,因而不会处理ValueError
print("异常类型不匹配,程序终止")
输入一个整数: asdf
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
in
1 try:
----> 2 x = int(input("输入一个整数: "))
3 y = x * x
4 print("y = {}".format(y))
5 except ZeroDivisionError:
ValueError: invalid literal for int() with base 10: 'asdf'
try:
x = int(input("输入一个整数: "))
y = x * x
print("y = {}".format(y))
except:
# except后面未指定任何异常类型则表示捕获所有类型的异常
print("except后面没有指定异常类型,则可以处理任意类型的异常")
输入一个整数: asdf
except后面没有指定异常类型,则可以处理任意类型的异常
try:
x = int(input("输入一个整数: "))
y = x * x
print("y = {}".format(y))
except OSError:
print("如果发生了OSError则在这里处理")
except ValueError:
print("如果发生了ValueError则在这里处理")
except TypeError:
print("如果发生了TypeError则在这里处理")
except:
print("还可以重新抛出异常,在Python中使用raise抛出异常")
raise
输入一个整数: asdf
如果发生了ValueError则在这里处理
在Python中使用raise
抛出异常,raise
后面可以跟异常类型
try:
# 手动抛出异常
raise ValueError("这是一个ValueError,准备好处理它吧")
except ValueError:
print("好的,收到ValueError,这就处理")
好的,收到ValueError,这就处理
在处理异常的时候,我们还可以添加finally
做一些后处理逻辑
try:
x = int(input("输入一个整数: "))
y = x * x
print("y = {}".format(y))
except ValueError:
print("输入异常,你输入的不是一个整数")
finally:
# 不管有没有发生异常,在执行完try内的代码之后,最终都要执行finally内的代码
# 典型的应用场景是在发生异常后我们需要关闭数据库连接,网络连接,关闭文件等等,这些操作比较适合写在finally中
print("不管有没有发生异常都要执行finally中的代码")
输入一个整数: asadf
输入异常,你输入的不是一个整数
不管有没有发生异常都要执行finally中的代码
以下为Python内置的异常
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StopAsyncIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ImportError
| +-- ModuleNotFoundError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
| +-- RecursionError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- ResourceWarning
除了使用Python内置的异常外,我们还可以自定义异常,自定义异常时我们需要继承Exception
类
class MyException(Exception):
"""定义一个简单的自定义异常类型"""
pass
try:
# 在try中抛出MyException异常
raise MyException("抛出MyException异常")
except MyException:
# 在此处处理MyException异常
print("ok, 捕获到MyException异常,接下来处理MyException异常")
ok, 捕获到MyException异常,接下来处理MyException异常