异常处理
概述
在Python中,在处理可能会引发异常的代码块时,使用try
和except
语句。可以帮助我们捕获并处理异常,
而不是让程序因为一个未处理的异常而完全崩溃。
try-except
try-except-finally
try-finally
try-except-else
try-except-else-finally
操作
捕获特定异常
除数异常
try:
# 尝试进行可能出错的操作
num = 10 / 0
except ZeroDivisionError as e:
# 捕获所有异常并打印错误信息
print(f"发生了一个错误: {e}")
类型异常
try:
# 尝试将字符串和整数相加
num = 10
str = "abc"
result = num + str
print(f"结果是: {result}")
except TypeError:
# 捕获类型错误并打印错误信息
print("错误: 不能将整数和字符串相加。")
捕获多个异常
try:
# 尝试进行除法运算
num1 = int(input("请输入一个被除数: "))
num2 = int(input("请输入一个除数: "))#0 或者 z
result = num1 / num2
print(f"结果是: {result}")
except ZeroDivisionError:
# 捕获除零错误并打印错误信息
print("错误: 不能除以零。")
except ValueError:
# 捕获输入非数字的错误并打印错误信息
print("错误: 请输入有效的整数。")
捕获多个异常的另一种写法
try:
# 尝试进行除法运算
num1 = int(input("请输入一个被除数: "))
num2 = int(input("请输入一个除数: "))
result = num1 / num2
print(f"结果是: {result}")
except (ZeroDivisionError, ValueError):
print("错误: 不能除以零。")
print("错误: 请输入有效的整数。")
使用finally语句
(无论是否发生异常都会执行)
try:
# 尝试进行除法运算
result = 10 / 0
print(f"结果是: {result}")
except ZeroDivisionError:
# 捕获除零错误并打印错误信息
print("错误: 不能除以零。")
finally:
# 无论是否发生异常,都会执行的代码块
print("程序执行完毕。")
使用else语句
(仅在未发生异常时执行)
try:
# 尝试执行的代码
result = 10 / 1
except ZeroDivisionError:
print("不能除以零!")
else:
# 如果未发生异常,则执行此代码块,发生异常则不会执行
print(f"结果是:{result}")
抛出异常
在 Python 里,可以使用raise关键字手动抛出异常。
try:
num = 1 / 0
except ZeroDivisionError as e:
raise ZeroDivisionError("捕获到除零错误")
也可以抛出自定义异常
class MyCustomError(Exception):
pass
try:
num = 1 / 1
except ZeroDivisionError as e:
raise MyCustomError("发生了自定义异常")
常见的异常
-
语法错误(SyntaxError)
#描述:当Python代码不符合语法规则时抛出。 #示例:忘记在语句末尾添加冒号。 if True print("Hello, World!")
缩进错误(IndentationError)
#描述:当代码的缩进不符合Python的缩进规则时抛出。 #示例:缩进不一致。 def example(): print("This line has incorrect indentation.")
除零错误(ZeroDivisionError)
#描述:当尝试除以零或取模运算时抛出。 result = 1 / 0
名称错误(NameError)
#描述:当使用一个未定义的变量或函数名时抛出。 print(unknown_variable)
值异常(ValueError)
#描述:当函数接收到一个类型正确但值不合适的参数时抛出。 #示例:尝试将一个非数字字符串转换为整数 num = int("abc")
类型错误(TypeError)
# 尝试将字符串和整数相加 result = "Hello" + 123
索引错误(IndexError)
#描述:当尝试访问序列(如列表、元组或字符串)中不存在的索引时抛出 my_list = [1, 2, 3] print(my_list[3])
键错误(KeyError)
# 描述:当尝试访问字典中不存在的键时抛出。 my_dict = {'a': 1, 'b': 2} print(my_dict['c'])
文件未找到错误(FileNotFoundError)
# 没有读取到xxx.txt文件 with open('xxx.txt', 'r') as file: content = file.read() print(content)
属性错误(AttributeError)
# 示例:将非数字字符串转换为整数 num = int("abc") # 描述:当尝试访问对象不存在的属性或方法时抛出。 my_list = [1, 2, 3] print(my_list.nonexistent_method())
IO操作
概述
I/O (输入/输出)
I/O (input/output)
内存读取外部(包括来自磁盘、光盘等存储设备的数据)属于输入
内存写到外部磁盘属于输出
os.path
使用os.path模块操作目录
os.path模块是 Python 内置的与操作系统功能和文件系统相关的模块。该模块的子模块 os.path 是专门用于进行路径操作的模块。常用
的路径操作主要有判断目录是否存在、创建目录、删除目录和遍历目录等。
import os
import time
# 获取绝对路径
p1 = os.path.abspath("test1.txt")
print(p1)
# 查看文件是否存在
# print(os.path.exists(p1))
# 查看文件是否为文件
# print(os.path.isfile(p1))
# 查看文件是否为目录 访问一个真实目录
# print(os.path.isdir(p1))
# 查看文件的大小
# print(os.path.getsize(p1))
# 查看文件的创建时间 时间戳
# print(os.path.getctime(p1))
# 查看文件的修改时间 时间戳
# print(os.path.getmtime(p1))
# 查看文件的访问时间 时间戳
# print(os.path.getatime(p1))
# 时间戳转时间
# print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(os.path.getctime(p1))))
# print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(os.path.getmtime(p1))))
# print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(os.path.getatime(p1))))
打开文件
基本读取
# 以默认方式打开文件
f = open("./test.txt")
# content = f.read()
# print(content)
# 以迭代器方式打开文件
for line in f:
print(line)
需要释放流资源
f = open("test.txt")
try:
content = f.read()
print(content)
finally:
f.close()
with语句处理资源关闭
在 Python 里,可以使用with语句来释放资源,像文件操作、网络连接、数据库连接这类需要在使用完毕后释放资源。
with open("test.txt") as f:
content = f.read()
print(content)
文件打开模式
下面是一些常见的打开文件的模式:
-
'r'
: 读取模式,打开文件以供读取(默认)。 -
'w'
: 写入模式,打开文件以供写入,如果文件已存在,则覆盖原有内容。 -
'a'
: 追加模式,打开文件以供写入,如果文件已存在,则在文件末尾追加内容。 -
'+'
读写 模式, 可与其他模式结 合使用 。 比如 r+代表读写模式 , w+代表读写模式,rb+代表二进制读写模式 -
'b'
: 二进制模式,用于处理二进制文件。
读取模式
with open("test.txt", 'r') as f:
content = f.read()
print(content)
移动文件指针: 使用seek()
方法可以移动文件指针到指定位置:
# 移动文件指针到指定位置
file_path = 'test.txt'
with open(file_path, 'r') as file:
file.seek(2) # 移动到文件的第2个字符位置开始读取
content = file.read()
print(content)
写入模式
file_path = 'test.txt'
with open(file_path, 'w') as file:
file.write('Hello, World!\n')
file.write('This is a sample text.')
file_path = 'test.txt'
with open(file_path, 'w') as file:
# write方法接受一个字符串作为参数
file.write('Hello, World1!')
file.write('Hello, World2!\n')
# writelines方法可以接受字符串和字符串序列(如列表、元组等)作为参数
file.writelines(['Hello, World4!', 'Hello, World5!'])
write和writeline二者都不会加换行符,需要自己手动添加换行符
追加模式
file_path = 'test.txt'
with open(file_path, 'w') as file:
file.write('Hello\n')
with open(file_path, 'a') as file:
file.write('World\n')
读写模式
# 打开一个文本文件进行读写
with open('test.txt', 'r+', encoding='utf-8') as file:
# 读取文件内容
content = file.read()
print("读取的内容:", content)
new_text = "\n这是在读写模式下追加的内容。"
file.write(new_text)
按行读取文件内容
codecs模块下的open()打开文件可以按照行读取
-
readline:读取一 行内容 。 如果指定了参数 n ,则只读取此行内的 n 个字符(每一行读几个字符参数n决定)。
-
readlines : 读取文件内所有行 。
import codecs f = codecs.open('test.txt', 'r', encoding='utf-8') while True: content = f.readline() if not content: break print(content) f.close()
使用readlines方法,将文件中所有行都读入到一个列表中
import codecs f = codecs.open('test.txt', 'r', encoding='utf-8') # 使用readlines方法,将文件中所有行都读入到一个列表中 print(f.readlines()) # for content in f.readlines(): # print(content) f.close()
os模块的IO函数
-
read 方法用于从文件中读取数据
-
write 方法用于向文件中写入数据
-
lseek 方法用于移动文件指针的位置。文件指针决定了后续读写操作的起始位置
-
os.SEEK_SET:从文件开头开始计算偏移量。
-
os.SEEK_END:从文件末尾开始计算偏移量。
-
文件描述:
-
os.O_CREAT 指定的文件不存在,则创建该文件
-
os.O_RDWR 代表以读写模式打开文件。既可以从文件中读取数据,也能够向文件里写入数据
import os fd = os.open('test.txt', os.O_CREAT | os.O_RDWR) os.write(fd, b'hello world') # 写入文件内容 b:创建了一个字节串 os.lseek(fd, 1, os.SEEK_SET) # 1是偏移值 从文件开头开始计算 data = os.read(fd, 1024) # 读取文件内容 print(data) os.close(fd)