Skip to content
返回

Python 错误处理与内置模块

目录

错误处理

错误大致可以分为三类:

异常处理机制

Python 提供了 try...except...finally 结构,可以让我们专门处理异常情况。

# 即使发生异常,文件也会被正确关闭。
try:
    file = open("test.txt", "w")  # 打开文件
    file.write("Hello, world!")
    # 故意制造一个异常
    1 / 0
except ZeroDivisionError:
    print("除零错误!")
finally:
    # 无论是否出错,这里都会执行
    file.close()
    print("文件已关闭")

# 可以针对不同的错误给出不同的提示
try:
    # 获取用户输入并转换为整数,可能抛出ValueError异常
    num = int(input("请输入一个整数:"))  # 可能输入非数字
    # 执行除法运算,可能抛出ZeroDivisionError异常
    result = 10 / num  # 可能除以0
# 捕获值错误异常(输入的不是有效数字时)
except ValueError:
    # 输出错误提示信息
    print("输入的不是有效的整数!")
# 捕获零除错误异常(除数为0时)
except ZeroDivisionError:
    # 输出错误提示信息
    print("不能除以0!")
# 如果try块中没有发生任何异常,则执行else块
else:
    # 如果没有发生异常,会执行这里
    # 输出计算结果
    print("计算结果是:", result)
# 无论是否发生异常,finally块都会被执行
finally:
    # 输出程序结束提示
    print("程序结束。")

如果一个函数内部发生了异常,但没有被捕获,异常会自动“传递”到调用它的函数,直到被捕获或者程序终止。

def func1():
    return 10 / 0  # 这里会抛出异常

def func2():
    return func1()  # 异常会传递到这里

try:
    func2()  # 在这里捕获异常
except ZeroDivisionError as e:
    print("捕获到异常:", e)

没有捕获异常,Python会输出完整的错误信息。

def a():
    return 1 / 0  # 这里出错

def b():
    return a()

def c():
    return b()

c()

记录错误日志

有时候我们希望把错误信息保存下来,方便以后分析。Python的 logging 模块可以帮助我们记录详细的错误日志,日志会包含详细的错误类型和调用栈信息。

import logging  # 导入日志模块

try:
    10 / 0  # 故意制造异常
except Exception as e:
    # 记录异常信息到日志
    logging.error("程序出错了:", exc_info=True)

print("程序继续运行")

主动抛出异常

# 定义一个自定义异常类,继承自Exception基类
class MyInputError(Exception):
    """自定义输入错误类型"""
    # 使用pass关键字表示类体为空,仅继承父类功能
    pass

# 定义一个检查正数的函数,接收一个数字参数
def check_positive(num):
    # 判断输入的数字是否小于等于0
    if num <= 0:
        # 主动抛出自定义异常
        # 使用raise关键字抛出自定义异常,并传递错误信息
        raise MyInputError("输入必须是正数!")
    # 如果数字为正数,则返回该数字
    return num

# 使用try-except语句处理可能出现的异常
try:
    # 调用check_positive函数,传入负数-5进行测试
    check_positive(-5)
# 捕获MyInputError类型的异常,并将异常对象赋值给变量e
except MyInputError as e:
    # 打印捕获到的自定义异常信息
    print("捕获到自定义异常:", e)
    
    
# 捕获后重新抛出
def func():
    try:
        1 / 0
    except ZeroDivisionError:
        print("这里先记录一下异常")
        raise  # 重新抛出异常

try:
    func()
except ZeroDivisionError:
    print("最终在这里处理异常")

代码调试

建议使用 Visual Studio Code、PyCharm 等现代 IDE,调试会更加直观。你只需要在代码行号旁边点击一下,就能设置断点,然后点击“调试”按钮,程序会自动在断点处暂停,可以在界面上查看变量、单步执行、甚至修改变量值;图形化界面更友好,调试效率更高,适合初学者和大型项目。

Python 自带 pdb 调试器,可以单步执行代码: python -m pdb your_script.py,调试器会停在第一行,可以用 n 命令逐行执行,用 p 变量名 查看变量值,用 q 退出调试。

import pdb

score_str = "0"
score = int(score_str)
pdb.set_trace() # 程序运行到这里会暂停,进入调试模式

print(100 / score)

assert

测试则是通过编写测试用例,确保程序的正确性,如果断言失败,程序会抛出 AssertionError,断言适合用来检查那些“理论上不应该出错”的地方,帮助我们提前发现潜在问题。

通过命令行参数关闭所有assert语句,-O 参数会关闭所有assert语句,提高程序运行效率,如: python -O your_script.py

def calculate_average(score_str):
    score = int(score_str)
    # 断言分数不能为0,否则会报错
    assert score != 0, "分数不能为0!"
    return 100 / score

def main():
    calculate_average('0')

main()

def add(a, b):
    return a + b

# 断言add(2, 3)的结果应该是5
assert add(2, 3) == 5, "加法结果不正确!"
print("测试通过")

logging

相比 printlogging 模块更适合在实际开发中使用。它可以灵活地设置输出级别(如debug、info、warning、error),并且可以把日志写到文件里,方便后续分析与后期统一管理和关闭调试信息。

import logging

# 设置日志输出级别为INFO
logging.basicConfig(level=logging.INFO)

def calculate_average(score_str):
    # 将字符串转换为整数
    score = int(score_str)
    # 用logging记录调试信息
    logging.info("分数已转换为整数:%d", score) # INFO:root:分数已转换为整数:0
    # 计算平均分
    return 100 / score

def main():
    calculate_average('0')

main()

单元测试

单元测试用来“自动检查”小模块,比如一个函数、一个类是否能正确工作。

如下面的代码:

import unittest  # 导入unittest模块
from mydict import MyDict  # 假设上面的类保存在mydict.py文件中

# 定义一个测试类,继承自unittest.TestCase
class TestMyDict(unittest.TestCase):
    def test_init(self):
        # 测试初始化和属性访问
        d = MyDict(a=1, b='hello')
        self.assertEqual(d.a, 1)  # 检查属性a的值
        self.assertEqual(d.b, 'hello')  # 检查属性b的值
        self.assertTrue(isinstance(d, dict))  # 检查d是否是dict的子类

    def test_key_access(self):
        # 测试通过key访问和赋值
        d = MyDict()
        d['x'] = 100
        self.assertEqual(d.x, 100)  # 检查属性x的值

    def test_attr_set(self):
        # 测试通过属性赋值
        d = MyDict()
        d.y = 200
        self.assertIn('y', d)  # 检查字典里是否有'y'
        self.assertEqual(d['y'], 200)  # 检查key为'y'的值

    def test_key_error(self):
        # 测试访问不存在的key时抛出KeyError
        d = MyDict()
        # 使用with self.assertRaises(KeyError)来检查是否抛出了KeyError异常
        with self.assertRaises(KeyError):
            _ = d['not_exist']

    def test_attr_error(self):
        # 测试访问不存在的属性时抛出AttributeError
        d = MyDict()
        with self.assertRaises(AttributeError):
            _ = d.not_exist

if __name__ == '__main__':
    unittest.main()  # 运行所有测试

这种运行方式需要文件中有 if __name__ == '__main__': unittest.main() 才能运行测试, 相当于手动调用 unittest.main()。 或者使用unittest模块运行:

python -m unittest

只运行指定的方法:

python -m unittest mydict_test.TestMyDict.test_attr_set

有时候,每个测试方法运行前后都需要做一些准备和清理工作,比如连接和关闭数据库。可以避免在每个测试方法里重复写相同的代码,这时可以用 setUp()tearDown() 方法:

class TestMyDict(unittest.TestCase):
    def setUp(self):
        # 每个测试方法运行前都会执行这里的代码
        print('准备测试环境...')

    def tearDown(self):
        # 每个测试方法运行后都会执行这里的代码
        print('清理测试环境...')

文档测试

文档测试的核心思想是:把代码的使用示例直接写在注释里,然后让Python自动检查这些示例是否真的能运行并得到预期结果。 这样,别人看你的代码时,既能看到清晰的用法示例,还能保证这些示例是经过验证的,避免“文档和实际不符”的尴尬。

doctest

Python自带了 doctest 模块,可以自动提取docstring里的示例代码并运行,检查实际输出和注释里写的是否一致,如下代码:

def my_abs(n):
    '''
    计算一个数的绝对值。

    >>> my_abs(2)
    2
    >>> my_abs(-8)
    8
    '''
    return n if n >= 0 else -n

if __name__ == '__main__':
    import doctest  # 导入doctest模块
    doctest.testmod()  # 自动运行当前模块中的所有doctest

异常情况

只要异常类型和最后一行的错误信息能对上,doctest 就会判定通过。

def get_item(lst, idx):
    '''
    获取列表指定位置的元素。

    >>> get_item([1, 2, 3], 1)
    2
    >>> get_item([1, 2, 3], 5)
    Traceback (most recent call last):
        ...
    IndexError: list index out of range
    '''
    return lst[idx]

内置模块

文件与操作

os 模块

import os

# 获取当前工作目录(即当前Python脚本运行的文件夹)
print("当前工作目录:", os.getcwd())

# 切换到指定目录(如切换到C盘根目录,注意Windows下路径用\\或r'路径')
os.chdir(r'C:\\')
print("切换后的工作目录:", os.getcwd())

# 创建一个新文件夹
os.mkdir('test_folder')  # 在当前目录下创建名为test_folder的文件夹

# 删除文件夹(只能删除空文件夹)
os.rmdir('test_folder')

# 列出当前目录下的所有文件和文件夹
print("当前目录内容:", os.listdir('.'))

# 获取操作系统的环境变量(如PATH)
print("系统PATH环境变量:", os.environ.get('PATH'))

# os.path

# 拼接路径(推荐用os.path.join,自动适配操作系统的分隔符)
full_path = os.path.join('folder', 'file.txt')
print("拼接后的路径:", full_path)

# 拆分路径,分离文件夹和文件名
folder, filename = os.path.split('folder/file.txt')
print("文件夹部分:", folder)
print("文件名部分:", filename)

# 判断文件是否存在
print("file.txt是否存在:", os.path.exists('file.txt'))

# 判断路径是否为文件
print("file.txt是文件吗:", os.path.isfile('file.txt'))

# 判断路径是否为文件夹
print("folder是文件夹吗:", os.path.isdir('folder'))

# 获取绝对路径
print("file.txt的绝对路径:", os.path.abspath('file.txt'))

# 获取文件扩展名
name, ext = os.path.splitext('file.txt')
print("文件名:", name)
print("扩展名:", ext)

shutil 模块

import os
import shutil

# 复制文件(把a.txt复制为b.txt)
shutil.copy('a.txt', 'b.txt')

# 复制整个文件夹(把src_folder复制为dst_folder)
shutil.copytree('src_folder', 'dst_folder')

# 移动文件或文件夹(也可以用来重命名)
shutil.move('b.txt', 'new_b.txt')  # 把b.txt移动或重命名为new_b.txt

# 删除文件
os.remove('new_b.txt')

# 删除整个文件夹及其内容
shutil.rmtree('dst_folder')

glob 模块

import glob

# 查找当前目录下所有txt文件
txt_files = glob.glob('*.txt')
print("所有txt文件:", txt_files)

# 查找所有子文件夹下的txt文件(递归查找)
all_txt_files = glob.glob('**/*.txt', recursive=True)
print("所有子文件夹下的txt文件:", all_txt_files)

tempfile 模块

import os
import tempfile

# 创建一个临时文件,返回文件对象
with tempfile.TemporaryFile(mode='w+t') as f:
    f.write('这是临时文件内容')
    f.seek(0)  # 回到文件开头
    print("临时文件内容:", f.read())
# 文件会在with语句结束后自动删除

# 创建一个临时目录
with tempfile.TemporaryDirectory() as tmpdirname:
    print("临时目录路径:", tmpdirname)
    # 可以在临时目录下创建文件
    filepath = os.path.join(tmpdirname, 'temp.txt')
    with open(filepath, 'w') as f:
        f.write('写入临时文件')
    # 读取刚才写入的内容
    with open(filepath, 'r') as f:
        print("读取临时文件内容:", f.read())
# 临时目录和里面的内容会自动删除

fnmatch 模块

import fnmatch

# 判断文件名是否以.txt结尾
print(fnmatch.fnmatch('report.txt', '*.txt'))  # 输出True

# 判断文件名是否以data_加两位数字结尾
print(fnmatch.fnmatch('data_01.csv', 'data_??.csv'))  # 输出True
print(fnmatch.fnmatch('data_1.csv', 'data_??.csv'))   # 输出False
-- 2025 年 10 月 7 日止 --

系统与运行环境

sys 模块

sys模块主要用于与Python解释器进行交互。你可以用它获取命令行参数、操作系统路径、退出程序等。它是写脚本和工具时非常常用的模块。

import sys  # 导入sys模块

# sys.argv是一个列表,包含了命令行参数
print("所有命令行参数:", sys.argv)  # 第一个参数是脚本名

# 获取第一个参数(脚本名)
print("脚本名:", sys.argv[0])

# 如果有额外参数,可以这样获取
if len(sys.argv) > 1:
    print("第一个用户输入的参数:", sys.argv[1])
else:
    print("没有输入额外参数")

# python 脚本名 参数1 参数2
# python 02.系统与运行环境.py hello
# 所有命令行参数: ['02.系统与运行环境.py', 'hello']
# 脚本名: 02.系统与运行环境.py
# 第一个用户输入的参数: hello

# sys模块可以获取和设置Python解释器的路径

# 获取Python解释器路径
print("Python解释器路径:", sys.executable)

# 设置Python解释器路径
sys.executable = "C:/Python311/python.exe"

print("程序即将退出")
sys.exit(0)  # 0表示正常退出,非0表示异常退出
print("这行不会被执行")  # 这行不会输出,因为上面已经退出

platform 模块

platform 模块可以帮助你获取当前操作系统的类型、版本、Python 解释器的版本等信息。常用于需要根据不同系统做兼容性处理的场景。

import platform  # 导入platform模块

# 获取操作系统名称
print("操作系统名称:", platform.system())  # 如 Windows、Linux、Darwin(macOS)

# 获取操作系统详细版本
print("操作系统详细版本:", platform.version())

# 获取完整平台信息
print("完整平台信息:", platform.platform())

# 获取Python版本
print("Python版本:", platform.python_version())

# 操作系统名称: Darwin
# 操作系统详细版本: Darwin Kernel Version 25.0.0: Wed Sep 17 21:41:45 PDT 2025; root:xnu-12377.1.9~141/RELEASE_ARM64_T6000
# 完整平台信息: macOS-26.0.1-arm64-arm-64bit
# Python版本: 3.11.11

getopt/argparse 模块

写脚本时,经常需要从命令行获取参数。getopt和argparse都是用来解析命令行参数的模块。getopt适合简单参数,argparse功能更强大,推荐新手用argparse。

python demo.py -f config.txt --verbose -n 张三 -a 20 input1.txt input2.txt
# demo_getopt.py
import sys, getopt

opts, args = getopt.getopt(sys.argv[1:], "f:n:a:", ["verbose"])
# 解析键值到变量
config = None
name = None
age = None
verbose = False

for opt, val in opts:
    if opt == '-f':
        config = val
    elif opt == '-n':
        name = val
    elif opt == '-a':
        age = int(val)
    elif opt == '--verbose':
        verbose = True

inputs = args  # 剩余的位置参数

print("config =", config)
print("verbose =", verbose)
print("name =", name, "age =", age)
print("inputs =", inputs)

# demo_argparse.py
import argparse

parser = argparse.ArgumentParser(description="示例:读取配置并处理输入文件")
parser.add_argument("-f", "--config", required=True, help="配置文件路径")
parser.add_argument("--verbose", action="store_true", help="开启详细日志")
parser.add_argument("-n", "--name", required=True, help="你的名字")
parser.add_argument("-a", "--age", type=int, required=True, help="你的年龄")
parser.add_argument("inputs", nargs="+", help="要处理的输入文件")

args = parser.parse_args()

print("config =", args.config)
print("verbose =", args.verbose)
print("name =", args.name, "age =", args.age)
print("inputs =", args.inputs)

logging 模块

import logging  # 导入logging模块

# 记录一条信息
logging.info("这是一条普通信息")  # 默认不会显示,因为默认级别是WARNING

# 记录一条警告
logging.warning("这是一个警告信息")

# 记录一条错误
logging.error("这是一个错误信息")

# 配置日志输出格式和级别
logging.basicConfig(
    level=logging.INFO,  # 设置日志级别为INFO
    format="%(asctime)s - %(levelname)s - %(message)s"  # 设置输出格式
)

logging.info("程序启动")
logging.warning("警告:磁盘空间不足")
logging.error("错误:文件未找到")

subprocess 模块

subprocess 模块可以让你在 Python 程序中运行外部命令(比如调用系统的dir、ls、ping等),还能获取命令的输出结果;它是自动化运维、脚本开发的利器。

import subprocess

# 运行命令并获取输出(以Windows的dir命令为例,Linux下可用ls)
result = subprocess.run("dir", shell=True, capture_output=True, text=True)

# 打印命令的输出内容
print("命令输出:")
print(result.stdout)

# 运行一个命令
result = subprocess.run("ping 127.0.0.1 -n 2", shell=True)

# 判断命令是否成功执行(返回码为0表示成功)
if result.returncode == 0:
    print("命令执行成功")
else:
    print("命令执行失败,返回码:", result.returncode)

日期和时间

time 模块

time模块主要用于处理时间戳、获取当前时间、让程序休眠等。它和操作系统的时间紧密相关,适合做一些底层的时间操作。

import time

# 获取当前时间戳(单位:秒,浮点数)
timestamp = time.time()
print("当前时间戳:", timestamp)

# 获取当前本地时间的结构体
local_time = time.localtime()
print("本地时间结构体:", local_time)

# 将时间戳转换为本地时间结构体
t = 1700000000
print("时间戳1700000000对应的本地时间:", time.localtime(t))

# 将本地时间结构体转换为字符串
time_str = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
print("格式化后的本地时间:", time_str)

# 将字符串时间转换为时间结构体
parsed_time = time.strptime("2024-01-01 12:00:00", "%Y-%m-%d %H:%M:%S")
print("解析后的时间结构体:", parsed_time)

print("开始休眠2秒")
time.sleep(2)  # 让程序暂停2秒
print("2秒后继续执行")
方法字母含义方向助记词
strftimefFormat对象 → 字符串Format”
strptimepParse字符串 → 对象Parse”

datetime 模块

datetime模块是Python中功能最强大的日期和时间处理模块。它可以方便地获取当前日期、时间,进行加减、比较等操作。

import datetime

# 获取当前日期和时间
now = datetime.datetime.now()
print("当前日期和时间:", now)

# 获取当前日期
today = datetime.date.today()
print("今天的日期:", today)

# 创建一个指定日期的date对象
d = datetime.date(2025, 12, 25)
print("指定日期:", d)

# 创建一个指定日期和时间的datetime对象
dt = datetime.datetime(2025, 12, 25, 15, 30, 0)
print("指定日期和时间:", dt)

# 加3天
three_days_later = now + datetime.timedelta(days=3)
print("三天后:", three_days_later)

# 减2小时
two_hours_ago = now - datetime.timedelta(hours=2)
print("两小时前:", two_hours_ago)

# datetime对象转为字符串
now = datetime.datetime.now()
now_str = now.strftime("%Y-%m-%d %H:%M:%S")
print("格式化后的时间字符串:", now_str)

# 字符串转为datetime对象
dt = datetime.datetime.strptime("2025-01-01 08:30:00", "%Y-%m-%d %H:%M:%S")
print("解析后的datetime对象:", dt)

calendar 模块

calendar模块可以用来生成日历、判断某天是星期几、判断闰年等,适合做日历和日期分析相关的功能。

import calendar

# 打印2025年5月的日历
print(calendar.month(2025, 5))

#       May 2025
# Mo Tu We Th Fr Sa Su
#           1  2  3  4
#  5  6  7  8  9 10 11
# 12 13 14 15 16 17 18
# 19 20 21 22 23 24 25
# 26 27 28 29 30 31

# 判断2025年是否为闰年
is_leap = calendar.isleap(2025)
print("2025年是闰年吗?", is_leap)

# 获取2025年5月的每周分布(每周是一个元组,0表示周一)
month_days = calendar.monthcalendar(2025, 5)
print("2025年5月的每周分布:", month_days)

# 0表示周一,6表示周日
weekday = calendar.weekday(2025, 5, 1)
print("2025年5月1日是: 星期", weekday + 1)

数学与数字处理

math 模块

import math

# 计算平方根
print("16的平方根:", math.sqrt(16))  # 输出4.0

# 计算绝对值
print("绝对值:", math.fabs(-5))  # 输出5.0

# 计算幂(2的3次方)
print("2的3次方:", math.pow(2, 3))  # 输出8.0

# 计算正弦、余弦、正切
print("sin(30°):", math.sin(math.radians(30)))  # 先将角度转为弧度
print("cos(60°):", math.cos(math.radians(60)))
print("tan(45°):", math.tan(math.radians(45)))

# 常用常数
print("圆周率π:", math.pi)
print("自然对数e:", math.e)

# 计算自然对数(以e为底)
print("ln(10):", math.log(10))  # 默认以e为底

# 计算以10为底的对数
print("log10(100):", math.log10(100))  # 输出2.0

# 向上取整
print("向上取整3.2:", math.ceil(3.2))  # 输出4

# 向下取整
print("向下取整3.8:", math.floor(3.8))  # 输出3

random 模块

import random

# 生成1到10之间的随机整数(包含1和10)
print("随机整数:", random.randint(1, 10))

# 生成0到1之间的随机小数
print("随机小数:", random.random())

# 从列表中随机选择一个元素
fruits = ["苹果", "香蕉", "橙子"]
print("随机选择水果:", random.choice(fruits))

# 打乱列表顺序
random.shuffle(fruits)
print("打乱后的水果列表:", fruits)

# 生成2到10之间,步长为2的随机偶数
print("随机偶数:", random.randrange(2, 11, 2))  # 可能输出2、4、6、8、10

decimal 模块

decimal 模块可以进行高精度的十进制计算,适合对精度要求很高的场合,比如财务、科学计算等。

from decimal import Decimal, getcontext

# 普通浮点数的加法(可能有精度误差)
print("0.1 + 0.2 =", 0.1 + 0.2)  # 输出0.30000000000000004

# 用Decimal进行高精度加法
a = Decimal("0.1")
b = Decimal("0.2")
print("Decimal高精度加法:", a + b)  # 输出0.3

# 设置全局小数精度为4位
getcontext().prec = 4

# 进行高精度运算
result = Decimal("1.23456") / Decimal("3")
print("保留4位有效数字的结果:", result)

fractions 模块

fractions模块可以用来进行分数的加减乘除,结果也是分数,非常适合需要精确分数表示的场景。

from fractions import Fraction

# 创建分数1/3
f1 = Fraction(1, 3)
print("分数1/3:", f1)

# 由字符串创建分数
f2 = Fraction("2/5")
print("分数2/5:", f2)

a = Fraction(1, 3)
b = Fraction(1, 6)

# 分数加法
print("1/3 + 1/6 =", a + b)

# 分数乘法
print("1/3 * 1/6 =", a * b)

statistics 模块

statistics模块可以方便地计算均值、中位数、方差等常用统计量,适合数据分析和科学计算。

import statistics

data = [1, 2, 3, 4, 5, 6]

# 计算均值
print("均值:", statistics.mean(data))

# 计算中位数
print("中位数:", statistics.median(data))

# 计算方差
# 方差指数据与均值之间的偏离程度
print("方差:", statistics.variance(data))

# 计算众数(出现次数最多的数)
print("众数:", statistics.mode(data))

字符串与文本处理

re 模块

re模块用于复杂的字符串匹配、查找、替换等操作;正则表达式是一种用特殊符号描述字符串规则的“语言”,可以高效地处理各种文本格式。

import re

# 判断字符串是否是手机号(以1开头,11位数字)
phone = "13812345678"
pattern = r"^1\d{10}$"  # 正则表达式:1开头,后面10个数字
if re.match(pattern, phone):
    print("手机号格式正确")
else:
    print("手机号格式不正确")

# 提取字符串中的所有数字
text = "小明今年18岁,身高175cm"
numbers = re.findall(r"\d+", text)  # 匹配所有连续数字
print("提取到的数字:", numbers)
# 提取到的数字: ['18', '175']

# 把字符串中的数字全部替换为X
text = "房间号:308,电话:123456"
new_text = re.sub(r"\d+", "X", text)
print("替换后的文本:", new_text)
# 替换后的文本: 房间号:X,电话:X

string 模块

string模块提供了很多常用的字符串处理工具,比如大小写转换、字符集常量等。虽然大部分字符串操作可以直接用str对象的方法,但string模块有些特殊用途。

import string

# 获取所有小写字母
print("小写字母:", string.ascii_lowercase)
# 小写字母: abcdefghijklmnopqrstuvwxyz
# 获取所有大写字母
print("大写字母:", string.ascii_uppercase)
# 大写字母: ABCDEFGHIJKLMNOPQRSTUVWXYZ
# 获取所有数字字符
print("数字字符:", string.digits)
# 数字字符: 0123456789

# 用f-string格式化字符串(推荐)
name = "小明"
age = 18
print(f"大家好,我是{name},今年{age}岁。")

# 用str.format格式化字符串
print("大家好,我是{},今年{}岁。".format(name, age))

textwrap 模块

textwrap模块可以让长文本自动换行,适合在命令行或输出到文件时美化排版。

import textwrap

# 一段很长的文本
long_text = "Python是一门非常流行的编程语言。它语法简洁,功能强大,应用广泛。"

# 自动换行,每行最多20个字符
wrapped = textwrap.fill(long_text, width=20)
print(wrapped)

# 带有缩进的多行文本
text = """
    这是第一行。
        这是第二行,有更多缩进。
    这是第三行。
"""

# 去除所有行的多余缩进
dedented = textwrap.dedent(text)
print(dedented)

difflib 模块

difflib模块可以用来比较两个字符串或文本的差异,常用于做文本对比、生成差异报告等。

import difflib

text1 = "Python是一门很棒的语言。"
text2 = "Python是一门非常棒的语言!"

# 生成差异对比
diff = difflib.ndiff(text1, text2)
print("\n".join(diff))

text1 = """Python是一门很棒的语言。
适合新手学习。"""
text2 = """Python是一门非常棒的语言!
适合零基础新手学习。"""

# 生成HTML格式的差异报告
d = difflib.HtmlDiff()
html = d.make_file(text1.splitlines(), text2.splitlines())
with open("diff_report.html", "w", encoding="utf-8") as f:
    f.write(html)
print("差异报告已生成:diff_report.html")
-- 2025 年 10 月 8 日止 --

文件格式与数据存储

json 模块

import json

# 定义一个Python字典
data = {"name": "小明", "age": 18, "score": [90, 85, 92]}

# 将Python对象转换为JSON字符串
json_str = json.dumps(data, ensure_ascii=False)  # ensure_ascii=False可以输出中文
print("转换后的JSON字符串:", json_str)

# 定义一个JSON格式的字符串
json_str = '{"name": "小明", "age": 18, "score": [90, 85, 92]}'

# 将JSON字符串转换为Python对象
data = json.loads(json_str)
print("转换后的Python对象:", data)

# 写入JSON文件
data = {"city": "北京", "temp": 25}
with open("data.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False)

# 读取JSON文件
with open("data.json", "r", encoding="utf-8") as f:
    loaded = json.load(f)
    print("从文件读取的数据:", loaded)

csv 模块

import csv

# 准备要写入CSV文件的数据,使用二维列表结构
# 第一行是表头,后面的行是具体的学生数据
rows = [
    # 表头行,定义各列的名称
    ["姓名", "年龄", "成绩"],
    # 第一个学生的信息:姓名、年龄、成绩
    ["小明", 18, 90],
    ["小红", 17, 95],
]

# 使用with语句打开文件,确保文件会被正确关闭
# 'w'表示写入模式,newline=''防止出现空行,encoding='utf-8'确保中文正确显示
with open("students.csv", "w", newline="", encoding="utf-8") as f:
    # 创建CSV写入器对象,用于将数据写入文件
    writer = csv.writer(f)
    # 一次性写入所有行数据到CSV文件
    writer.writerows(rows)
# 打印提示信息,告知用户文件写入操作已完成
print("CSV文件写入完成")

# 读取CSV文件
with open("students.csv", "r", encoding="utf-8") as f:
    reader = csv.reader(f)
    for row in reader:
        print("读取到一行:", row)

# 取到一行: ['姓名', '年龄', '成绩']
# 读取到一行: ['小明', '18', '90']
# 读取到一行: ['小红', '17', '95']

configparser 模块

configparser 模块用于读取和写入类似于Windows ini格式的配置文件,常用于保存程序的配置信息。

假设有一个配置文件 config.ini 内容如下:

[DEFAULT]
username = admin
password = 123456

[server]
host = localhost
port = 8080
import configparser

# 创建配置解析器对象
config = configparser.ConfigParser()

# 读取配置文件
config.read('config.ini', encoding='utf-8')

# 获取DEFAULT区的username
print("用户名:", config['DEFAULT']['username'])

# 获取server区的host和port
print("服务器地址:", config['server']['host'])
print("服务器端口:", config['server']['port'])

# 添加内容
config['DEFAULT'] = {'username': 'admin', 'password': '123456'}
config['server'] = {'host': 'localhost', 'port': '8080'}

# 写入到文件
with open('config.ini', 'w', encoding='utf-8') as f:
    config.write(f)
print("配置文件写入完成")

pickle 模块

pickle模块可以把Python对象保存到文件中,也可以从文件中恢复出来。常用于保存程序运行状态、缓存数据等。

import pickle

# 定义一个Python对象
data = {"name": "小明", "age": 18, "score": [90, 85, 92]}

# 序列化并写入文件
with open("data.pkl", "wb") as f:  # 注意用二进制写入
    pickle.dump(data, f)
print("对象已序列化保存")

# 从文件读取并反序列化
with open("data.pkl", "rb") as f:
    loaded = pickle.load(f)
    print("反序列化得到的对象:", loaded)

加密和安全

哈希算法

哈希算法(也叫散列算法)是一种将任意长度的数据“压缩”成固定长度字符串的算法。常见的哈希算法有MD5、SHA1、SHA256等。哈希值常用于密码存储、文件校验、防篡改等场景。主要特点

import hashlib

# 原始字符串
text = "hello world"

# 创建MD5哈希对象
md5 = hashlib.md5()
# 必须先将字符串编码为字节
md5.update(text.encode("utf-8"))
# 获取16进制的哈希值
print("MD5哈希值:", md5.hexdigest())
# 导入hashlib模块,用于计算各种哈希值

# 使用with语句打开文件,'rb'模式表示以二进制只读方式打开
# 打开文件,读取内容
with open("README.md", "rb") as f:
    # 创建一个SHA1哈希对象
    sha1 = hashlib.sha1()
    # 使用无限循环来分块读取文件内容,这样可以处理大文件而不会占用过多内存
    # 分块读取,适合大文件
    while True:
        # 每次读取1024字节的数据
        data = f.read(1024)
        # 如果读取到的数据为空,说明文件已经读取完毕
        if not data:
            # 跳出循环
            break
        # 将读取到的数据块更新到SHA1哈希对象中
        sha1.update(data)
    # 计算最终的SHA1哈希值并以十六进制字符串形式输出
    print("文件的SHA1哈希值:", sha1.hexdigest())

text = "python123"

# 计算MD5
md5 = hashlib.md5(text.encode("utf-8")).hexdigest()
print("MD5:", md5)

# 计算SHA1
sha1 = hashlib.sha1(text.encode("utf-8")).hexdigest()
print("SHA1:", sha1)

# 计算SHA256
sha256 = hashlib.sha256(text.encode("utf-8")).hexdigest()
print("SHA256:", sha256)

hmac 模块

HMAC(Hash-based Message Authentication Code,基于哈希的消息认证码)是一种常用的消息加密校验方式。它结合了哈希算法和密钥,可以防止数据在传输过程中被篡改。常用于:

import hashlib
import hmac

# 消息内容
message = b"hello, world"
# 密钥(双方约定的“密码”)
key = b"my_secret_key"

# 创建HMAC对象,指定密钥和哈希算法
h = hmac.new(key, message, digestmod=hashlib.sha256)
# 获取16进制的HMAC值
print("HMAC签名:", h.hexdigest())


def verify_hmac(message, key, received_hmac):
    # 重新生成HMAC
    h = hmac.new(key, message, digestmod=hashlib.sha256)
    # 比较HMAC值
    return h.hexdigest() == received_hmac


# 假设收到如下数据
msg = b"hello, world"
key = b"my_secret_key"
received = hmac.new(key, msg, digestmod=hashlib.sha256).hexdigest()

# 校验
if verify_hmac(msg, key, received):
    print("数据未被篡改,校验通过")
else:
    print("数据被篡改,校验失败")

网络与互联网

urllib 模块

urllib模块是Python自带的网络请求工具,可以用来抓取网页、下载文件、解析URL等。常用子模块有urllib.requesturllib.parse等。

from urllib import request, parse

# 发送GET请求,获取网页内容
response = request.urlopen("https://www.example.com")
# 读取网页内容(字节类型)
html = response.read()
# 将字节内容解码为字符串
print("网页内容:", html.decode("utf-8"))

url = "https://www.example.com/search?q=python&lang=zh"
# 解析URL为各部分
result = parse.urlparse(url)
print("协议:", result.scheme)
print("主机:", result.netloc)
print("路径:", result.path)
print("查询参数:", result.query)

# 字典转为URL参数字符串
params = {"q": "python", "lang": "zh"}
query_str = parse.urlencode(params)
print("编码后的参数:", query_str)

# URL参数字符串转为字典
parsed = parse.parse_qs("q=python &lang=zh")
print("解码后的参数:", parsed)

http.client 模块

http.client模块可以让你用底层方式发送HTTP请求,适合需要自定义请求头、方法等高级用法。

import http.client

# 创建HTTP连接对象
conn = http.client.HTTPSConnection("www.example.com")
# 发送GET请求
conn.request("GET", "/")
# 获取响应
response = conn.getresponse()
print("状态码:", response.status)
print("响应内容:", response.read().decode("utf-8"))
# 关闭连接
conn.close()

# 创建一个HTTPS连接对象,连接到www.example.com服务器
conn = http.client.HTTPSConnection("www.example.com")
# 定义要发送的POST数据,格式为URL编码的字符串
params = "name=Tom&age=18"
# 设置HTTP请求头,指定内容类型为表单数据格式
headers = {"Content-type": "application/x-www-form-urlencoded"}
# 发送POST请求到/submit路径,包含参数和请求头
conn.request("POST", "/submit", params, headers)
# 获取服务器的响应对象
response = conn.getresponse()
# 读取响应内容并解码为UTF-8格式,然后打印输出
print("POST响应内容:", response.read().decode("utf-8"))
# 关闭HTTP连接,释放资源
conn.close()

smtplib 模块

import smtplib
from email.mime.text import MIMEText

# 邮件内容
msg = MIMEText("你好,这是一封测试邮件。", "plain", "utf-8")
# 发件人、收件人、主题
msg["From"] = "from@qq.com"
msg["To"] = "to@qq.com"
msg["Subject"] = "测试邮件"

# 连接QQ邮箱SMTP服务器并登录
server = smtplib.SMTP_SSL("smtp.qq.com", 465)
server.login("from@qq.com", "your_password")
# 发送邮件
server.sendmail("from@qq.com", ["to@qq.com"], msg.as_string())
# 关闭连接
server.quit()
print("邮件发送成功")

socket 模块

socket模块是Python最底层的网络通信接口,可以实现自定义的网络协议、聊天程序等。

import socket

# 创建TCP套接字
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定IP和端口
server.bind(("127.0.0.1", 8888))
# 开始监听 1指的是最大连接数
server.listen(1)
print("服务器已启动,等待连接...", server.getsockname())

# 接受客户端连接
conn, addr = server.accept()
print("连接来自:", addr)
# 接收数据
data = conn.recv(1024)
print("收到客户端数据:", data.decode("utf-8"))
# 发送回复
conn.send(b"Hello, client!")
# 关闭连接
conn.close()
server.close()socket_server.python
import socket

# 创建TCP套接字
# AF_INET: 使用IPv4地址族
# SOCK_STREAM: 使用TCP协议
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接服务器
client.connect(("127.0.0.1", 8888))
# 发送数据
client.send(b"Hello, server!")
# 接收数据
data = client.recv(1024)
print("收到服务器回复:", data.decode("utf-8"))
# 关闭连接
client.close()socket_client.py

其它模块

copy 模块

import copy

# 定义一个嵌套列表
lst1 = [1, 2, [3, 4]]

# 浅拷贝:只复制最外层,内部嵌套对象还是同一个
lst2 = copy.copy(lst1)
lst2[2][0] = 99
print("浅拷贝后lst1:", lst1)  # [1, 2, [99, 4]]

# 深拷贝:递归复制所有层级,完全独立
lst3 = copy.deepcopy(lst1)
lst3[2][0] = 100
print("深拷贝后lst1:", lst1)  # [1, 2, [99, 4]]
print("深拷贝后lst3:", lst3)  # [1, 2, [100, 4]]

enum 模块

from enum import Enum

# 定义一个星期的枚举类型
class Weekday(Enum):
    MON = 1
    TUE = 2
    WED = 3
    THU = 4
    FRI = 5
    SAT = 6
    SUN = 7

# 使用枚举
today = Weekday.MON
print("今天是:", today)
print("今天的值:", today.value)
print("今天的名字:", today.name)

uuid 模块

import uuid

# 生成一个随机的UUID(版本4)
unique_id = uuid.uuid4()
print("随机UUID:", unique_id)

# 生成基于名字的UUID(版本5)
name_id = uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
print("基于名字的UUID:", name_id)

base64 模块

import base64

# 原始字符串
text = "hello world"
# 编码为字节
text_bytes = text.encode("utf-8")
# Base64编码
encoded = base64.b64encode(text_bytes)
print("Base64编码:", encoded)

# Base64解码
decoded = base64.b64decode(encoded)
print("解码后字符串:", decoded.decode("utf-8"))

# 读取文件并编码为Base64
with open("README.md", "rb") as f:
    img_data = f.read()
    encoded = base64.b64encode(img_data)
    print("Base64编码前10字节:", encoded[:10])

# 解码Base64并写入新文件
with open("README.md", "wb") as f:
    f.write(base64.b64decode(encoded))

struct 模块

import struct

# `i`表示整数,`f`表示浮点数,顺序要和打包时一致。

# 打包:把整数12345和浮点数3.14编码为二进制
packed = struct.pack('if', 12345, 3.14)
print("打包后的二进制数据:", packed)

# 解包:从二进制数据还原为原始数据
unpacked = struct.unpack('if', packed)
print("解包后的数据:", unpacked)

typing 模块

typing模块用于为变量、函数参数和返回值添加类型提示,让代码更规范、易读,适合团队协作和大型项目。

from typing import List, Optional, Tuple

# 定义一个加法函数,参数x和y都是整数类型,返回值也是整数类型
def add(x: int, y: int) -> int:
    # 返回两个数的和
    return x + y

# 定义一个问候函数,参数names是字符串列表,无返回值
def greet(names: List[str]) -> None:
    # 遍历名字列表中的每个名字
    for name in names:
        # 打印问候语和当前名字
        print("你好,", name)

# 使用类型提示
# 调用add函数计算2+3的结果
result = add(2, 3)
# 调用greet函数问候小明和小红
greet(["小明", "小红"])

# 定义一个查找用户的函数,参数是用户ID(整数类型),返回值是可选的元组(包含姓名和年龄)
# Optional[Tuple[str, int]] 表示返回值可以是一个元组,也可以是None。
def find_user(user_id: int) -> Optional[Tuple[str, int]]:
    # 假设查找不到返回None
    # 如果用户ID等于1,返回用户信息
    if user_id == 1:
        # 返回包含姓名和年龄的元组
        return ("小明", 18)
    # 如果用户ID不等于1,返回None表示未找到
    else:
        return None

# 调用函数查找ID为1的用户并打印结果
print(find_user(1))
# 调用函数查找ID为2的用户并打印结果
print(find_user(2))
-- 2025 年 10 月 9 日止 --

配套代码:vsme/learn-python



下一篇
Python I/O 编程与多任务