Python中的异常处理、文件操作 和 模块的使用
·
一、 异常处理 (Exception)
1. 完整结构
try:
# 可能出错的代码
except (ValueError, TypeError) as e:
# 捕获特定异常(可多个)
except Exception as e:
# Exception 万能异常(BaseException 的子类)
else:
# 未发生异常时执行
finally:
# 无论是否有异常,最终都会执行(常用于关闭文件/数据库)
# 常见异常
# IndexError
# ValueError
# NameError
# TypeError
# IndentationError
# FileExistsError
# FileNotFoundError
2. 主动抛出异常 (raise)
用于人为中断程序执行。
if age < 0:
raise ValueError("年龄不能为负数")
3. 断言 (assert)
用于内部调试,条件为假时触发 AssertionError。
assert len(list) > 0, "列表不能为空"
# 若条件为真,继续执行;为假,崩溃并提示。
4. 总结
try...except捕获,raise主动抛,assert快速检查
二、 文件操作 (File I/O)
1. 基础流程
- 核心步骤:打开 (
open) →\rightarrow→ 操作 (read/write) →\rightarrow→ 关闭 (close)。 - 推荐写法:使用
with语句(上下文管理器),执行完毕自动关闭文件,更安全。
with open('文件路径', mode='文件模式', encoding='utf-8 | gbk') as file_obj:
# 打开多个文件,逗号分隔:open('路径1','w',encoding='utf-8‘) as file_obj2
2. 路径与编码
- 相对路径:
./(当前目录),../(上一级目录)。推荐使用,方便项目移植。 - 绝对路径:从根目录开始的完整路径。
- 编码:文本文件建议显式指定
encoding='utf-8'。
3. 常用模式 (Mode)
| 模式 | 描述 | 文件不存在时 | 文件存在时 |
|---|---|---|---|
| r | 读 (默认) | 报错 | 正常读取 |
| w | 覆盖写 | 创建新文件 | 清空原内容再写 |
| a | 追加写 | 创建新文件 | 在末尾接着写 |
| x | 独占写 | 创建新文件 | 报错 (防止覆盖) |
| b | 二进制 | 处理图片/音频/视频,如 rb, wb |
- |
| + | 更新 | 增强功能,如 r+ (可读可写) |
- |
| r+ | read+write | 抛出异常 | 正常打开 |
| w+ | write+read | 创建文件 | 清空内容 |
| a+ | append+read | 创建文件 | 正常打开 |
| 后缀 | 说明 | 返回类型 | 示例 |
|---|---|---|---|
| t | 文本文件(默认) | str字符串 | rt、wt |
| b | 二进制文件(图片/音频等) | bytes 字节码 | rb、wb |
4. 代码示例
基础读写:
# 同时打开多个文件:从 f1 读,写入 f2
with open('data.txt', 'r', encoding='utf-8') as f1, open('backup.txt', 'w') as f2:
for line in f1:
content = line.strip() # 去除行末换行符 \n 和空格
f2.write(content + '\n')
二进制读写(图片/PDF):
with open('logo.png', 'rb') as f:
data = f.read() # 读取的是字节码 b'\x...'
常用函数:
| 方法 | 返回类型 | 示例 | 说明 |
|---|---|---|---|
read(size) |
str / bytes |
"Hello" 或 b"Hello" |
读取最多 size 个字符/字节,省略则读全部 |
readline(size) |
str / bytes |
"Hello\n" 或 b"Hello\n" |
读取一行(含换行符),size 限制每行最大长度 |
readlines(hint) |
list |
["Hello\n", "World\n"] |
读取所有行,返回列表。hint 为字节数建议(不切分行) |
readable() |
bool |
True / False |
判断文件是否可读 |
write(s) |
int |
5 |
写入字符串/字节串,返回写入的字符/字节数 |
writelines(lines) |
None |
None |
写入字符串列表(不会自动添加换行符) |
writable() |
bool |
True / False |
判断文件是否可写 |
close() |
None |
None |
关闭文件,释放资源 |
closed (属性) |
bool |
False |
属性(非方法),判断文件是否已关闭 |
flush() |
None |
None |
强制将缓冲区数据写入磁盘 |
seek(offset, whence) |
int |
10 |
移动文件指针到指定位置,返回新位置 |
tell() |
int |
0 |
返回当前文件指针的位置(字节数) |
truncate(size) |
int |
100 |
截断文件到指定大小(字节),省略则截断到当前位置 |
isatty() |
bool |
False |
判断文件是否关联到一个终端设备 |
fileno() |
int |
3 |
返回文件描述符(整数,供底层操作系统使用) |
不调用 flush() 时,数据也会提前写入磁盘的情况
- 缓冲区满了(默认8KB)
f = open('test.txt', 'w')
for i in range(10000):
f.write("a" * 100) # 写入约 1MB 数据
# 缓冲区每满 8KB 会自动刷一次,不需要 flush()
f.close()
- 行缓冲模式(
buffering=1)
f = open('test.txt', 'w', buffering=1)
f.write("第一行\n") # 遇到换行符自动刷,不需要 flush()
- 无缓冲模式(
buffering=0,仅二进制)
f = open('test.txt', 'wb', buffering=0)
f.write(b"Hello") # 每次 write 都直接写磁盘,不需要 flush()
- 程序正常结束(Python 会自动清理缓冲区)
f = open('test.txt', 'w')
f.write("Hello")
# 没有 flush,没有 close
# 但程序正常结束时,Python 会自动刷新缓冲区
write()调用完成流程图如下:
write() 调用
↓
数据进入【内存缓冲区】
↓
触发自动刷新的条件:
├── 缓冲区满了(8KB)
├── 遇到换行符(行缓冲模式)
├── 调用 flush()
├── 调用 close()
├── 程序正常结束
└── 程序崩溃 → ❌ 数据丢失!
函数细节
f2 = open('test.txt', mode='wt') # ← 覆盖发生在这里!
f2.write('12345') # 写入到已清空(或新建)的文件
f2.write('abcde1') # 追加到当前文件指针位置(不是覆盖)
f2.close()
f = open('./test.txt', mode='a+', encoding='utf-8')
print(f.tell()) # 输出文件指针位置,通常是文件的总字节数(末尾)
print(f.read()) # 从末尾开始读,读不到任何内容
5. 注意事项
- 换行符:读取每一行时,末尾通常带有
\n,处理数据建议配合.strip()。 - 写权限:
w模式极其危险,打开瞬间就会清空原文件。 - 异常处理:可以在
with内部嵌套try...except捕获读写过程中的异常。
6. 总结
- 读用
r,改用w(覆盖) 或a(追加)。 - 非文本文件必带
b。 - 永远优先使用
with open(...)。
三、 模块的使用 (Modules)
1. 导入模块的四种格式
# 格式 1:导入整个模块
import math
print(math.sqrt(16)) # 4.0
# 格式 2:从模块导入具体功能 (推荐,避免使用 *)
from math import sin, pi
print(sin(pi/2)) # 1.0
# 格式 3:设置别名 (简化长模块名)
import datetime as dt
now = dt.datetime.now()
# 格式 4:从包/子包中导入
import xml.etree.ElementTree as ET
# ET.parse()
模块注意事项
- 导入:优先使用
from 模块 import 函数。 - 别名:
as可以让代码更简洁(如numpy as np)。 - 数学:基础计算用
math模块,复杂科学计算通常用numpy。 - 搜索路径:Python 会先在当前目录找模块,找不到再去系统库路径找。
- 标准库 vs 第三方库:
- 标准库:Python自带(如
math,os,sys),直接导入。 - 第三方库:需先通过
pip install 库名安装后方可使用。
- 标准库:Python自带(如
2. math 内置模块常用功能
2.1 常用math函数
math 模块提供了丰富的数学运算函数:
- 常用常量:
math.pi: 圆周率 π\piπmath.e: 自然对数底数 eee
- 数值处理:
ceil(x): 向上取整。美/siːl /floor(x): 向下取整。sqrt(x): 开平方。square root美 /skwer ruːt/pow(x, y): 求幂,x 的 y 次方。trunc(x):截取整数。truncate美 /ˈtrʌŋkeɪt/gcd(*integers):最大公约数
import math
# 1. 常量与数值处理
print(math.pi) # 3.1415926... (圆周率)
print(math.e) # 2.7182818... (自然对数底数)
print(math.ceil(3.1)) # 4 (向上取整)
print(math.floor(3.9)) # 3 (向下取整)
print(math.sqrt(16)) # 4.0 (开平方)
print(math.pow(2, 3)) # 8.0 (2的3次方)
- 三角函数 (传入弧度):
sin(x),cos(x),tan(x):正弦、余弦、正切。asin(x),acos(x),atan(x):反三角函数。
# 2. 三角函数 (注意:参数均为弧度制)
# 将 30度 转换为弧度 美 /ˈreɪdiənz/
angle = math.radians(30)
print(math.sin(angle)) # 0.49999999999999994 (约等于0.5)
print(math.cos(angle)) # 0.866...
print(math.tan(angle)) # 0.577...
# 反三角函数
print(math.asin(0.5)) # 返回弧度
print(math.degrees(math.asin(0.5))) # 30.0 (弧度转角度)
# 3. 双曲函数
print(math.sinh(1)) # 双曲正弦
print(math.cosh(1)) # 双曲余弦
print(math.tanh(1)) # 双曲正切
2.2
常见角度的三角函数值表
| 角度 (θ) | 弧度 (rad) | sin θ | cos θ | tan θ |
|---|---|---|---|---|
| 0° | 0 | 0 | 1 | 0 |
| 30° | π/6 | 1/2 = 0.5 | √3/2 ≈ 0.8660 | 1/√3 ≈ 0.5774 |
| 45° | π/4 | √2/2 ≈ 0.7071 | √2/2 ≈ 0.7071 | 1 |
| 60° | π/3 | √3/2 ≈ 0.8660 | 1/2 = 0.5 | √3 ≈ 1.7321 |
| 90° | π/2 | 1 | 0 | 无穷大 (未定义) |
| 180° | π | 0 | -1 | 0 |
| 270° | 3π/2 | -1 | 0 | 无穷大 (未定义) |
| 360° | 2π | 0 | 1 | 0 |
常见输入值对应的反三角函数结果
| 输入 x | arcsin(x) | arccos(x) | arctan(x) |
|---|---|---|---|
| -1 | −π/2(−90°) | π(180°) | −π/4(−45°) |
| -√3/2 ≈ -0.8660 | −π/3(−60°) | 5π/6(150°) | −π/3(−60°) |
| -√2/2 ≈ -0.7071 | −π/4(−45°) | 3π/4(135°) | −π/4(−45°) |
| -1/2 = -0.5 | −π/6(−30°) | 2π/3(120°) | −π/6(−30°) |
| 0 | 0(0°) | π/2(90°) | 0(0°) |
| 1/2 = 0.5 | π/6(30°) | π/3(60°) | π/6(30°) |
| √2/2 ≈ 0.7071 | π/4(45°) | π/4(45°) | π/4(45°) |
| √3/2 ≈ 0.8660 | π/3(60°) | π/6(30°) | π/3(60°) |
| 1 | π/2(90°) | 0(0°) | π/4(45°) |
常见 x 值对应的双曲函数值表
| x | sinh x | cosh x | tanh x |
|---|---|---|---|
| 0 | 0 | 1 | 0 |
| 0.5 | ≈ 0.5211 | ≈ 1.1276 | ≈ 0.4621 |
| 1 | ≈ 1.1752 | ≈ 1.5431 | ≈ 0.7616 |
| 1.5 | ≈ 2.1293 | ≈ 2.3524 | ≈ 0.9051 |
| 2 | ≈ 3.6269 | ≈ 3.7622 | ≈ 0.9640 |
| 2.5 | ≈ 6.0502 | ≈ 6.1323 | ≈ 0.9866 |
| 3 | ≈ 10.0179 | ≈ 10.0677 | ≈ 0.9951 |
| 4 | ≈ 27.2899 | ≈ 27.3082 | ≈ 0.9993 |
| 5 | ≈ 74.2030 | ≈ 74.2099 | ≈ 0.9999 |
常见输入 y 对应的反双曲函数值表
| 输入 y | arsinh y | arcosh y | artanh y |
|---|---|---|---|
| -2 | ≈ -1.4436 | 无定义(y<1) | ≈ -0.5493 |
| -1 | ≈ -0.8814 | 无定义(y<1) | 无定义(|y|≥1) |
| -0.5 | ≈ -0.4812 | 无定义(y<1) | ≈ -0.5493 |
| 0 | 0 | 无定义(y<1) | 0 |
| 0.5 | ≈ 0.4812 | 无定义(y<1) | ≈ 0.5493 |
| 1 | ≈ 0.8814 | 0 | 无定义(|y|=1 时趋于无穷) |
| 1.5 | ≈ 1.1948 | ≈ 0.9624 | 无定义(|y|≥1) |
| 2 | ≈ 1.4436 | ≈ 1.3170 | 无定义(|y|≥1) |
| 3 | ≈ 1.8184 | ≈ 1.7627 | 无定义(|y|≥1) |
| 5 | ≈ 2.3124 | ≈ 2.2924 | 无定义(|y|≥1) |
- 对数函数:
log(x[, base]): 默认以 eee 为底,也可指定底数。log2(x): 以 2 为底。log10(x): 以 10 为底。
# 2. 对数函数
print(math.log(8, 2)) # 3.0 (以2为底,8的对数)
print(math.log10(100)) # 2.0 (以10为底)
print(math.log2(8)) # 3.0 (以2为底)
print(math.log(math.e)) # 1.0 (已e为底)
math模块注意事项
- 弧度制转换:
math.sin/cos/tan等函数接收的是弧度。- 角度转弧度:
math.radians(degrees) - 弧度转角度:
math.degrees(radians)
- 角度转弧度:
- 精度:
math.sqrt和math.pow返回的都是浮点数(float)。 - 对数:
math.log(x, base)如果不写第二个参数,默认以 eee 为底(即 lnx\ln xlnx)。
3. 系统操作 (os & os.path)
3.1. 目录与文件操作
- 创建目录:
os.mkdir(path):创建单层目录,若已存在则报错。os.makedirs(path, exist_ok=True):推荐。递归创建多层目录,exist_ok=True可防止目录已存在时报错。
- 删除文件:
os.remove(path)。
3.2. 路径检测与拆分 (os.path)
import os
path = '/Users/data/test.py'
# 常用检测
os.path.exists(path) # 路径是否存在
os.path.isdir(path) # 是否为目录
os.path.isfile(path) # 是否为文件
os.path.getsize(path) # 获取文件大小 (B)
# 路径处理
os.path.abspath('t.py') # 获取绝对路径
os.path.basename(path) # 获取文件名 -> 'test.py'
os.path.split(path) # 拆分为 (目录, 文件名)
os.path.splitext(path) # 拆分为 (路径名, .扩展名) -> (..., '.py')
# 路径拼接 (智能处理斜杠)
os.path.join('a', 'b', 'c.txt') # 'a/b/c.txt'
# 注意:若出现多个绝对路径(/开头),以最后一个为准
os.path.join('/a', '/b') # 结果为 '/b'
四、 随机数 (random)
1. 随机数值生成
random.random():生成[0, 1)之间的浮点数。random.randint(a, b):生成[a, b]之间的整数(包含 b)。random.uniform(a, b):生成[a, b]之间的浮点数。random.randrange(start, stop, step):按步长生成随机整数(左闭右开)。random.seed(n):设置随机种子,固定种子后生成的随机数序列不变。
2. 序列操作 (List/Tuple)
import random
lst = [1, 2, 3, 4, 5]
random.choice(lst) # 随机抽取 1 个元素
random.sample(lst, k=3) # 随机抽取 k 个不重复元素(返回新列表)
random.shuffle(lst) # 【原地】打乱列表顺序,无返回值
3. 加权随机抽取 (choices)
- 格式:
random.choices(seq, weights=None, k=n) - 特点:可重复抽取,支持权重(概率)。
- 权重逻辑:
weights=[1, 2, 7]意味着三个元素被抽中的概率分别为 10%、20%、70%。
# 示例:根据权重随机抽 20 次
colors = ['红', '绿', '蓝']
res = random.choices(colors, weights=[1, 1, 8], k=20)
# '蓝' 出现的次数理论上占 80%
总结备忘
- os:处理文件夹建议用
makedirs(..., exist_ok=True);拼接路径必用os.path.join。 - random:
- 拿一个用
choice。 - 拿多个(不重复)用
sample。 - 拿多个(按概率/可重复)用
choices。 - 打乱原顺序用
shuffle。
- 拿一个用
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)