3.1 os 模块 - 操作系统接口
概念:os 模块的作用
os 模块提供了与操作系统交互的接口,用于文件和目录操作、路径处理、环境变量访问等。它是 Python 中处理文件系统相关任务最常用的模块。
路径操作
python
import os
# 获取当前工作目录
print(os.getcwd()) # d:\kaicofile\trae\study_python
# 切换目录
os.chdir("path/to/dir") # 切换工作目录
# 创建目录
os.mkdir("new_folder") # 创建单个目录
os.makedirs("a/b/c") # 递归创建目录
# 删除目录
os.rmdir("empty_folder") # 删除空目录
import shutil
shutil.rmtree("folder") # 递归删除目录树
# 检查路径
os.path.exists("file.txt") # 路径是否存在
os.path.isfile("file.txt") # 是否是文件
os.path.isdir("folder") # 是否是目录
os.path.islink("link") # 是否是链接
路径拼接与分解
python
import os
# 路径拼接(自动处理不同系统的分隔符)
path = os.path.join("folder", "subfolder", "file.txt")
# Windows: "folder\subfolder\file.txt"
# Linux/Mac: "folder/subfolder/file.txt"
# 路径分解
print(os.path.split("/home/user/file.txt"))
# ('/home/user', 'file.txt')
# 获取文件名和目录名
print(os.path.basename("/home/user/file.txt")) # file.txt
print(os.path.dirname("/home/user/file.txt")) # /home/user
# 获取文件扩展名
print(os.path.splitext("file.txt"))
# ('file', '.txt')
# 获取绝对路径
print(os.path.abspath("file.txt"))
文件属性操作
python
import os
from datetime import datetime
# 文件大小
print(os.path.getsize("file.txt")) # 字节数
# 文件修改时间
mtime = os.path.getmtime("file.txt")
print(datetime.fromtimestamp(mtime))
# 列出目录内容
print(os.listdir(".")) # 返回列表
# 遍历目录树
for dirpath, dirnames, filenames in os.walk("."):
print(f"目录: {dirpath}")
print(f"子目录: {dirnames}")
print(f"文件: {filenames}")
环境变量
python
import os
# 获取环境变量
print(os.environ.get("PATH"))
print(os.environ.get("HOME", "default")) # 提供默认值
# 设置环境变量
os.environ["MY_VAR"] = "value"
# 执行系统命令(慎用)
# os.system("ls -la")
3.2 sys 模块 - 系统参数
概念:sys 模块的作用
sys 模块提供了对 Python 解释器相关参数的访问,用于命令行参数、系统平台信息、模块搜索路径、stdin/stdout/stderr 等。它是 Python 与解释器交互的桥梁。
命令行参数
python
import sys
# sys.argv: 命令行参数列表
# python script.py arg1 arg2
print(sys.argv) # ['script.py', 'arg1', 'arg2']
# 退出程序
sys.exit(0) # 正常退出
sys.exit(1) # 异常退出
sys.exit("错误信息") # 带消息退出
解释器信息
python
import sys
# Python 版本
print(sys.version) # 3.9.0
print(sys.version_info) # sys.version_info(major=3, minor=9, micro=0)
# 平台信息
print(sys.platform) # win32 / linux
# 最大递归深度
print(sys.getrecursionlimit()) # 1000
sys.setrecursionlimit(2000)
# 字节码缓存目录
print(sys.dont_write_bytecode) # False
# 模块搜索路径
print(sys.path)
# ['', 'C:\\Python39', 'C:\\Python39\\lib', ...]
stdin / stdout / stderr
python
import sys
# 标准输入/输出/错误
sys.stdout.write("Hello\n") # 输出到stdout
sys.stderr.write("Error occurred\n") # 输出到stderr
# 重新定向
import io
sys.stdout = io.StringIO() # 重定向输出
print("Hello") # 写入 StringIO
sys.stdout.seek(0)
print(sys.stdout.read()) # 读取内容
3.3 pathlib 模块 - 面向对象的路径操作
概念:pathlib 的优势
pathlib 是 Python 3.4 引入的模块,提供了面向对象的文件系统路径操作。相比 os.path,它更加直观和简洁,支持链式调用,是现代 Python 编程推荐的方式。
基础使用
python
from pathlib import Path
# 创建路径对象
p = Path("folder", "subfolder", "file.txt")
# 路径拼接
p = Path("folder") / "subfolder" / "file.txt"
# 获取路径组件
print(p.name) # file.txt(文件名)
print(p.stem) # file(不含扩展名)
print(p.suffix) # .txt(扩展名)
print(p.parent) # folder/subfolder(父目录)
print(p.parents) # 可迭代的父目录列表
# 路径判断
p.is_file() # 是否是文件
p.is_dir() # 是否是目录
p.exists() # 是否存在
p.is_absolute() # 是否是绝对路径
p.is_symlink() # 是否是符号链接
路径操作
python
from pathlib import Path
p = Path("folder/file.txt")
# 创建目录
p.parent.mkdir(parents=True, exist_ok=True)
# 文件操作
p.read_text() # 读取文本
p.read_bytes() # 读取二进制
p.write_text("Hello") # 写入文本
p.write_bytes(b"Hello") # 写入二进制
# 获取绝对路径
print(p.resolve())
# 获取相对路径
print(p.relative_to(Path("folder")))
# glob 模式匹配
list(Path(".").glob("*.py")) # 当前目录的 py 文件
list(Path(".").glob("**/*.py")) # 递归所有 py 文件
目录遍历
python
from pathlib import Path
base = Path(".")
# 迭代目录内容
for p in base.iterdir():
print(p.name)
# 递归遍历(类似 os.walk)
for p in base.rglob("*.py"): # 递归 glob
print(p)
# 统计目录大小
total = sum(f.stat().st_size for f in Path(".").rglob("*") if f.is_file())
3.4 json 模块 - JSON 序列化
概念:什么是 JSON?
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,常用于 API 数据传输和配置文件。Python 的 json 模块提供了 JSON 与 Python 对象之间的相互转换功能。
基本使用
python
import json
# Python 对象转 JSON 字符串
data = {"name": "Alice", "age": 25, "city": "Beijing"}
json_str = json.dumps(data)
print(json_str)
# {"name": "Alice", "age": 25, "city": "Beijing"}
# JSON 字符串转 Python 对象
python_obj = json.loads(json_str)
print(python_obj)
# {'name': 'Alice', 'age': 25, 'city': 'Beijing'}
# 文件操作
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
with open("data.json", "r", encoding="utf-8") as f:
data = json.load(f)
格式化选项
python
import json
data = {"name": "Alice", "scores": [90, 85, 88]}
# 缩进
print(json.dumps(data, indent=4))
# 中文显示
print(json.dumps(data, ensure_ascii=False))
# 键排序
print(json.dumps(data, sort_keys=True))
# 自定义序列化
def custom_serializer(obj):
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError(f"Object of type {type(obj)} is not JSON serializable")
json.dumps({"time": datetime.now()}, default=custom_serializer)
自定义编码器
python
import json
from datetime import datetime
class DateTimeEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat()
return super().default(obj)
data = {"name": "Alice", "created": datetime.now()}
print(json.dumps(data, cls=DateTimeEncoder, indent=2))
3.5 datetime 模块 - 日期时间处理
概念:datetime 模块的组成
datetime 模块包含四个主要类:datetime(日期时间)、date(日期)、time(时间)、timedelta(时间差)。timedelta 用于日期时间的算术运算,而 strftime/strptime 用于字符串与日期时间的相互转换。
datetime 类
python
from datetime import datetime, date, time, timedelta
# 获取当前时间
now = datetime.now()
print(now) # 2024-01-15 10:30:45.123456
# 获取当前日期
today = date.today()
print(today) # 2024-01-15
# 创建指定时间
dt = datetime(2024, 1, 15, 10, 30, 45)
print(dt)
# 获取各个组件
print(dt.year, dt.month, dt.day)
print(dt.hour, dt.minute, dt.second, dt.microsecond)
# 星期几(0=周一,6=周日)
print(dt.weekday()) # 0
print(dt.isoweekday()) # 1
日期时间格式化
python
from datetime import datetime
dt = datetime(2024, 1, 15, 10, 30, 45)
# datetime 转字符串
print(dt.strftime("%Y-%m-%d %H:%M:%S")) # 2024-01-15 10:30:45
print(dt.strftime("%Y/%m/%d")) # 2024/01/15
print(dt.strftime("%B %d, %Y")) # January 15, 2024
print(dt.strftime("%I:%M %p")) # 10:30 AM
# 字符串转 datetime
dt = datetime.strptime("2024-01-15 10:30:45", "%Y-%m-%d %H:%M:%S")
# 常用格式符号
# %Y 四位年份 %y 两位年份
# %m 月份 %d 日期
# %H 24小时制 %I 12小时制
# %M 分钟 %S 秒
# %p AM/PM %B 月份全名
# %a 星期缩写 %w 星期数字
时间差 timedelta
python
from datetime import datetime, timedelta
now = datetime.now()
one_week_later = now + timedelta(weeks=1)
three_days_ago = now - timedelta(days=3)
# 计算时间差
delta = datetime(2024, 1, 20) - datetime(2024, 1, 15)
print(delta.days) # 5
print(delta.total_seconds()) # 432000.0
# 时间加减
future = now + timedelta(hours=2, minutes=30)
past = now - timedelta(days=7)
时区处理
python
from datetime import datetime, timezone, timedelta
# 创建带时区的时间
utc_now = datetime.now(timezone.utc)
print(utc_now)
# 创建指定时区的时间
tz_shanghai = timezone(timedelta(hours=8))
shanghai_time = datetime(2024, 1, 15, 10, 30, tzinfo=tz_shanghai)
# 时区转换
import pytz # 需要安装:pip install pytz
# shanghai_time.astimezone(pytz.timezone('America/New_York'))
3.6 collections 模块 - 容器数据类型
概念:collections 模块的作用
collections 模块提供了 Python 内置容器类型(dict、list、set、tuple)之外的更多数据结构,包括命名元组、有序字典、默认值字典、队列、链式映射等,能帮助你更高效地处理数据。
namedtuple - 命名元组
python
from collections import namedtuple
# 创建命名元组
Point = namedtuple("Point", ["x", "y"])
p = Point(10, 20)
print(p.x, p.y) # 10 20
print(p[0], p[1]) # 10 20
print(p._fields) # ('x', 'y')
# 命名元组的方法
print(p._asdict()) # {'x': 10, 'y': 20}
p2 = p._replace(x=30) # 返回新的命名元组
print(p2) # Point(x=30, y=20)
# 检查属性是否存在
print(hasattr(p, 'x')) # True
# 继承命名元组
class Point3D(Point):
pass
defaultdict - 默认值字典
python
from collections import defaultdict
# 创建带默认值的字典
dd = defaultdict(int) # 默认值是 0
dd["apple"] += 1
print(dd["apple"]) # 1
print(dd["banana"]) # 0(自动创建)
# 常用默认值类型
dd_list = defaultdict(list)
dd_list["fruits"].append("apple")
print(dd_list["fruits"]) # ['apple']
dd_set = defaultdict(set)
dd_set["numbers"].add(1)
print(dd_set["numbers"]) # {1}
# 工厂函数
dd = defaultdict(lambda: "default")
print(dd["key"]) # default
Counter - 计数器
python
from collections import Counter
# 统计元素出现次数
cnt = Counter(["a", "b", "a", "c", "a", "b"])
print(cnt) # Counter({'a': 3, 'b': 2, 'c': 1})
# 从字符串统计
cnt = Counter("abracadabra")
print(cnt) # Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
# 统计结果
print(cnt.most_common(3)) # 出现最多的3个 [('a', 5), ('b', 2), ('r', 2)]
print(cnt.most_common()) # 所有,按次数排序
# 操作
cnt["x"] = 0
print(list(cnt.elements())) # ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'c', 'd', 'r', 'r']
# 运算
c1 = Counter(a=3, b=1)
c2 = Counter(a=1, b=2)
print(c1 + c2) # Counter({'a': 4, 'b': 3})
print(c1 - c2) # Counter({'a': 2}) 只保留正数
print(c1 & c2) # 交集,取较小值
print(c1 | c2) # 并集,取较大值
OrderedDict - 有序字典
python
from collections import OrderedDict
# Python 3.7+ 普通字典已保证有序,但 OrderedDict 在早期版本有用
od = OrderedDict()
od["a"] = 1
od["b"] = 2
od["c"] = 3
# 移动元素到末尾
od.move_to_end("a")
# 删除并返回最后一个元素
od.popitem(last=True)
# 指定位置插入(3.7+ 不保证支持)
# od.move_to_end("d", last=False)
deque - 双端队列
python
from collections import deque
# 创建双端队列
dq = deque([1, 2, 3, 4, 5])
# 头部/尾部操作
dq.append(6) # 尾部添加
dq.appendleft(0) # 头部添加
dq.pop() # 尾部删除
dq.popleft() # 头部删除
# 限制最大长度(超出自动删除对端)
dq = deque(maxlen=3)
dq.append(1)
dq.append(2)
dq.append(3)
dq.append(4) # 自动删除头部 1
print(list(dq)) # [2, 3, 4]
# 旋转
dq = deque([1, 2, 3, 4, 5])
dq.rotate(2) # 右旋2位
print(list(dq)) # [4, 5, 1, 2, 3]
dq.rotate(-2) # 左旋2位
print(list(dq)) # [1, 2, 3, 4, 5]
# 扩展
dq.extend([6, 7, 8])
dq.extendleft([-1, -2])
ChainMap - 链式映射
python
from collections import ChainMap
# 链式查找多个字典
dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}
dict3 = {"c": 5, "d": 6}
chain = ChainMap(dict1, dict2, dict3)
print(chain["a"]) # 1(第一个字典)
print(chain["b"]) # 2(第一个字典)
print(chain["c"]) # 4(第二个字典)
print(chain["d"]) # 6(第三个字典)
# 获取所有字典
print(chain.maps) # [dict1, dict2, dict3]
# 新建 ChainMap(会创建新字典)
new_chain = chain.new_child({"a": 10})
print(new_chain["a"]) # 10(新的字典)
3.7 itertools 模块 - 迭代器工具
概念:itertools 的作用
itertools 提供了用于创建和操作迭代器的高效工具函数。这些函数都返回迭代器,可以惰性求值,适合处理大数据或无限序列,在 Python 性能优化中非常重要。
无限迭代器
python
import itertools
# count: 无限计数
for i in zip(range(5), itertools.count(10)):
print(i) # (0, 10), (1, 11), (2, 12), (3, 13), (4, 14)
# count 可以指定步长和起始值
for i in itertools.count(0, 2): # 0, 2, 4, 6...
if i > 10:
break
print(i)
# cycle: 无限循环
for i, c in zip(range(8), itertools.cycle("ABC")):
print(f"{i}: {c}")
# repeat: 重复元素
for item in itertools.repeat("A", 3):
print(item) # A, A, A
# repeat 用于 map
print(list(itertools.starmap(pow, [(2, 3), (3, 2)])))
有限迭代器
python
import itertools
# accumulate: 累积计算
print(list(itertools.accumulate([1, 2, 3, 4, 5]))) # [1, 3, 6, 10, 15]
print(list(itertools.accumulate([1, 2, 3, 4], lambda x, y: x * y))) # [1, 2, 6, 24]
# chain: 连接多个迭代器
print(list(itertools.chain([1, 2], ['a', 'b'], [True, False])))
# chain.from_iterable: 扁平化
nested = [[1, 2], [3, 4], [5, 6]]
print(list(itertools.chain.from_iterable(nested))) # [1, 2, 3, 4, 5, 6]
# compress: 按条件过滤
data = [1, 2, 3, 4, 5]
selectors = [True, False, True, False, True]
print(list(itertools.compress(data, selectors))) # [1, 3, 5]
# dropwhile / takewhile
print(list(itertools.dropwhile(lambda x: x < 3, [1, 2, 3, 4, 1]))) # [3, 4, 1]
print(list(itertools.takewhile(lambda x: x < 3, [1, 2, 3, 4, 1]))) # [1, 2]
# filterfalse: 过滤不满足条件的
print(list(itertools.filterfalse(lambda x: x < 3, [1, 2, 3, 4]))) # [3, 4]
#islice: 切片迭代器
print(list(itertools.islice(range(10), 3))) # [0, 1, 2]
print(list(itertools.islice(range(10), 2, 8, 2))) # [2, 4, 6]
# pairwise: 相邻配对 (Python 3.10+)
# print(list(itertools.pairwise(range(5)))) # [(0,1), (1,2), (2,3), (3,4)]
# zip_longest: 长度不一时填充
from itertools import zip_longest
print(list(zip_longest([1, 2, 3], [4, 5], fillvalue=0)))
# [(1, 4), (2, 5), (3, 0)]
组合迭代器
python
import itertools
# product: 笛卡尔积
print(list(itertools.product([1, 2], ['a', 'b'])))
# [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]
# repeat 参数
print(list(itertools.product([1, 2], repeat=2)))
# [(1, 1), (1, 2), (2, 1), (2, 2)]
# permutations: 排列
print(list(itertools.permutations([1, 2, 3], 2)))
# [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]
# combinations: 组合
print(list(itertools.combinations([1, 2, 3], 2)))
# [(1, 2), (1, 3), (2, 3)]
# combinations_with_replacement: 带重复组合
print(list(itertools.combinations_with_replacement([1, 2], 2)))
# [(1, 1), (1, 2), (2, 2)]
3.8 functools 模块 - 函数式编程工具
概念:functools 模块的作用
functools 模块提供了用于高阶函数(接收或返回函数的函数)的工具,是 Python 函数式编程的基础。它包含装饰器、偏函数、函数缓存、函数包装等工具。
lru_cache - 函数缓存
python
import functools
# LRU 缓存:自动缓存函数调用结果
@functools.lru_cache(maxsize=128)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(100)) # 快速返回
# 缓存信息
print(fibonacci.cache_info())
# CacheInfo(hits=98, misses=101, ...)
# 清空缓存
# fibonacci.cache_clear()
# unbounded 缓存
@functools.lru_cache(maxsize=None)
def heavy_computation(x):
return x ** 2
partial - 偏函数
python
import functools
# 创建偏函数:预设部分参数
def power(base, exponent):
return base ** exponent
# 固定 exponent=2
square = functools.partial(power, exponent=2)
print(square(5)) # 25
# 固定 base=2
cube = functools.partial(power, 2) # 位置参数
print(cube(3)) # 8
# 与 lambda 结合
base_5_add = functools.partial(lambda x, y: x + y, 5)
print(base_5_add(3)) # 8
reduce - 累计计算
python
import functools
# reduce: 对序列进行累计计算
result = functools.reduce(lambda x, y: x + y, [1, 2, 3, 4, 5])
print(result) # 15
# 带初始值
result = functools.reduce(lambda x, y: x + y, [1, 2, 3, 4, 5], 10)
print(result) # 25
# 实现 max
print(functools.reduce(lambda a, b: a if a > b else b, [3, 1, 4, 1, 5, 9]))
# 实现 any
print(functools.reduce(lambda a, b: a or b, [False, False, True, False]))
# 实现 join
print(functools.reduce(lambda a, b: a + "," + b, ["a", "b", "c"]))
singledispatch - 单分派泛函数
python
import functools
# 单分派:根据第一个参数类型调用不同实现
@functools.singledispatch
def process(x):
print(f"默认处理: {x}")
@process.register(int)
def _(x):
print(f"整数: {x * 2}")
@process.register(str)
def _(x):
print(f"字符串: {x.upper()}")
@process.register(list)
def _(x):
print(f"列表: {len(x)} 项")
process(10) # 整数: 20
process("hello") # 字符串: HELLO
process([1, 2]) # 列表: 2 项
process(3.14) # 默认处理: 3.14
wraps 装饰器
python
import functools
# 保留原函数元信息
def my_decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print("调用前")
return func(*args, **kwargs)
return wrapper
@my_decorator
def greet(name):
"""问候函数"""
return f"Hello, {name}"
print(greet.__name__) # greet(原函数名)
print(greet.__doc__) # 问候函数(原文档)
3.9 logging 模块 - 日志记录
概念:日志级别
logging 模块是 Python 标准日志框架,支持多种日志级别:DEBUG(调试)、INFO(信息)、WARNING(警告)、ERROR(错误)、CRITICAL(严重错误)。通过配置,可以控制日志输出格式、目标和过滤器。
基础使用
python
import logging
# 创建 logger
logger = logging.getLogger(__name__)
# 设置级别
logger.setLevel(logging.DEBUG)
# 创建处理器
console_handler = logging.StreamHandler()
file_handler = logging.FileHandler("app.log", encoding="utf-8")
# 设置级别
console_handler.setLevel(logging.INFO)
file_handler.setLevel(logging.DEBUG)
# 设置格式
formatter = logging.Formatter(
"%(asctime)s - %(name)s - %(levelname)s - %(message)s",
datefmt="%Y-%m-%d %H:%M:%S"
)
console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)
# 添加处理器
logger.addHandler(console_handler)
logger.addHandler(file_handler)
# 记录日志
logger.debug("调试信息")
logger.info("普通信息")
logger.warning("警告信息")
logger.error("错误信息")
logger.critical("严重错误")
简化配置
python
import logging
# basicConfig: 快速配置
logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s - %(levelname)s - %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
handlers=[
logging.StreamHandler(),
logging.FileHandler("app.log", encoding="utf-8")
]
)
logging.debug("调试")
logging.info("信息")
logging.warning("警告")
日志器层级
python
import logging
# 根 logger
logging.basicConfig(level=logging.DEBUG)
# 子 logger
logger1 = logging.getLogger("myapp")
logger2 = logging.getLogger("myapp.database")
logger3 = logging.getLogger("myapp.web")
# 可以在不同层级设置不同级别
logging.getLogger("myapp").setLevel(logging.WARNING)
logging.getLogger("myapp.database").setLevel(logging.DEBUG)
日志轮转
python
import logging
from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler
# 按大小轮转
rotating = RotatingFileHandler(
"app.log",
maxBytes=1024 * 1024, # 1MB
backupCount=5 # 保留5个备份
)
logging.getLogger().addHandler(rotating)
# 按时间轮转
timed = TimedRotatingFileHandler(
"app.log",
when="midnight", # 每天午夜
interval=1,
backupCount=7 # 保留7天
)
logging.getLogger().addHandler(timed)
3.10 re 模块 - 正则表达式
概念:正则表达式的作用
正则表达式是一种强大的文本模式匹配工具,用于在字符串中查找、替换、提取特定模式的内容。Python 的 re 模块提供了完整的正则表达式支持,是处理文本数据的利器。
基础匹配
python
import re
# match: 从字符串开头匹配
result = re.match(r"\d+", "123abc")
print(result.group()) # 123
# search: 搜索第一个匹配
result = re.search(r"\d+", "abc123def456")
print(result.group()) # 123
# findall: 查找所有匹配
print(re.findall(r"\d+", "abc123def456")) # ['123', '456']
# finditer: 返回迭代器
for match in re.finditer(r"\d+", "abc123def456"):
print(match.group(), match.span())
# split: 按模式分割
print(re.split(r"\s+", "hello world python")) # ['hello', 'world', 'python']
# sub: 替换
print(re.sub(r"\d+", "#", "abc123def456")) # abc#def#
常用元字符
python
import re
# . 任意字符(除换行)
re.findall(r"a.c", "abc adc a1c") # ['abc', 'adc', 'a1c']
# \d 数字
re.findall(r"\d+", "abc123") # ['123']
# \w 字母数字下划线
re.findall(r"\w+", "hello_world!") # ['hello_world']
# \s 空白字符
re.findall(r"\s+", "a b\tc\nd") # [' ', '\t', '\n']
# ^ $ 开头结尾
re.search(r"^hello", "hello world") # 匹配开头
re.search(r"world$", "hello world") # 匹配结尾
# [] 字符集
re.findall(r"[aeiou]", "hello") # ['e', 'o']
re.findall(r"[a-z]", "Hello") # ['e', 'l', 'l', 'o']
# [^] 否定字符集
re.findall(r"[^aeiou]", "hello") # ['h', 'l', 'l']
量词
python
import re
# * 0或多个(贪婪)
re.findall(r"ab*", "abbb aab") # ['abbb', 'ab']
# + 1或多个(贪婪)
re.findall(r"ab+", "abbb aab") # ['abbb', 'ab']
# ? 0或1个
re.findall(r"colou?r", "color colour") # ['color', 'colour']
# {n} 精确 n 个
re.findall(r"\d{4}", "12345678") # ['1234', '5678']
# {n,m} n到m个(贪婪)
re.findall(r"\d{2,4}", "12345678") # ['1234', '5678']
# {n,m}? 非贪婪
re.findall(r"\d{2,4}?", "12345678") # ['12', '34', '56', '78']
分组与捕获
python
import re
# 分组
match = re.search(r"(\d{4})-(\d{2})-(\d{2})", "2024-01-15")
print(match.group()) # 2024-01-15
print(match.group(1)) # 2024
print(match.group(2)) # 01
print(match.group(3)) # 15
print(match.groups()) # ('2024', '01', '15')
# 命名分组
match = re.search(r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})", "2024-01-15")
print(match.groupdict()) # {'year': '2024', 'month': '01', 'day': '15'}
# 非捕获分组
re.findall(r"(?:\d+)-(\d+)", "2024-01") # ['01']
# | 或
re.findall(r"cat|dog", "I have a cat and a dog") # ['cat', 'dog']
编译与标志
python
import re
# 编译正则表达式(提高效率)
pattern = re.compile(r"\d+")
print(pattern.findall("abc123def456")) # ['123', '456']
# 常用标志
re.IGNORECASE # i: 忽略大小写
re.MULTILINE # m: 多行模式
re.DOTALL # s: . 匹配换行
print(re.findall(r"hello", "HELLO Hello hello", re.IGNORECASE))
# ['HELLO', 'Hello', 'hello']
# 预编译时指定
pattern = re.compile(r"\d+", re.IGNORECASE | re.MULTILINE)
3.11 argparse 模块 - 命令行参数
概念:argparse 的作用
argparse 是 Python 标准库中用于处理命令行参数的模块。它可以自动生成帮助信息、进行参数类型验证、支持子命令,是编写命令行工具的首选。
基础使用
python
import argparse
# 创建解析器
parser = argparse.ArgumentParser(description="我的程序")
parser.add_argument("name", help="输入名称") # 位置参数
parser.add_argument("-v", "--verbose", action="store_true", help="详细输出")
parser.add_argument("-n", "--number", type=int, default=1, help="数字")
args = parser.parse_args()
# 使用
print(f"Hello, {args.name}")
print(f"Verbose: {args.verbose}")
print(f"Number: {args.number}")
# python script.py Alice -v -n 5
# Hello, Alice
# Verbose: True
# Number: 5
参数类型
python
import argparse
parser = argparse.ArgumentParser()
# 字符串参数
parser.add_argument("--name", type=str, default="World")
# 整数参数
parser.add_argument("--count", type=int, default=1)
# 浮点数参数
parser.add_argument("--rate", type=float, default=0.5)
# 布尔参数(store_true / store_false)
parser.add_argument("--verbose", action="store_true")
parser.add_argument("--quiet", action="store_false")
# 限制选项
parser.add_argument("--level", choices=["low", "medium", "high"], default="medium")
# 追加参数(多个值)
parser.add_argument("--exclude", nargs="*", default=[])
parser.add_argument("files", nargs="+") # 至少一个
args = parser.parse_args()
子命令
python
import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="command", help="子命令")
# 子命令: install
install_parser = subparsers.add_parser("install", help="安装")
install_parser.add_argument("package")
# 子命令: uninstall
uninstall_parser = subparsers.add_parser("uninstall", help="卸载")
uninstall_parser.add_argument("package")
args = parser.parse_args(["install", "numpy"])
if args.command == "install":
print(f"安装 {args.package}")
elif args.command == "uninstall":
print(f"卸载 {args.package}")
自定义帮助和验证
python
import argparse
import sys
def positive_int(value):
ivalue = int(value)
if ivalue <= 0:
raise argparse.ArgumentTypeError("必须是正整数")
return ivalue
parser = argparse.ArgumentParser(description="我的程序")
parser.add_argument("port", type=positive_int)
parser.add_argument("--host", default="localhost")
# 自定义帮助输出
parser.add_argument("-x", help=argparse.SUPPRESS) # 隐藏
# set_defaults: 设置默认值
parser.set_defaults(verbose=False)
args = parser.parse_args()
3.12 urllib 模块 - 网络请求
概念:urllib 的组成
urllib 是 Python 标准库中用于处理 URL 的模块,包含四个子模块:request(发送请求)、response(处理响应)、error(异常处理)、parse(URL解析)。它是 Python 进行 HTTP 请求的基础库。
URL 解析
python
from urllib import parse, request
# URL 编码
params = {"name": "张三", "age": 25}
encoded = parse.urlencode(params)
print(encoded) # name=%E5%BC%A0%E4%B8%89&age=25
# URL 解码
decoded = parse.unquote("name=%E5%BC%A0%E4%B8%89")
print(decoded) # name=张三
# URL 解析
url = "https://example.com:8080/path/to/page?name=value#section"
parsed = parse.urlparse(url)
print(parsed.scheme) # https
print(parsed.netloc) # example.com:8080
print(parsed.path) # /path/to/page
print(parsed.query) # name=value
print(parsed.fragment) # section
# URL 构建
url = parse.urlunparse(("https", "example.com", "/path", "", "name=value", ""))
print(url) # https://example.com/path?name=value
发送请求
python
from urllib import request, parse
# GET 请求
with request.urlopen("https://httpbin.org/get") as response:
print(response.status) # 200
print(response.read().decode())
# 带参数的 GET
params = parse.urlencode({"name": "Alice", "age": 25})
url = f"https://httpbin.org/get?{params}"
with request.urlopen(url) as response:
print(response.read().decode())
# POST 请求
data = parse.urlencode({"name": "Alice", "age": 25}).encode()
with request.urlopen("https://httpbin.org/post", data=data) as response:
print(response.read().decode())
# 设置请求头
req = request.Request(
"https://httpbin.org/headers",
headers={"User-Agent": "MyApp/1.0", "Accept": "application/json"},
method="GET"
)
with request.urlopen(req) as response:
print(response.read().decode())
错误处理
python
from urllib import request, error
try:
with request.urlopen("https://httpbin.org/status/404") as response:
print(response.status)
except error.HTTPError as e:
print(f"HTTP 错误: {e.code} {e.reason}")
except error.URLError as e:
print(f"URL 错误: {e.reason}")
except Exception as e:
print(f"其他错误: {e}")
处理 Cookies
python
from urllib import request
import http.cookiejar
# 创建 Cookie Jar
cookie_jar = http.cookiejar.CookieJar()
# 创建 opener
opener = request.build_opener(request.HTTPCookieProcessor(cookie_jar))
# 发送请求
response = opener.open("https://httpbin.org/cookies/set/test_cookie/hello")
print(cookie_jar) # CookieJar
# 再次请求,cookies 会自动发送
response = opener.open("https://httpbin.org/cookies")
print(response.read().decode())
3.13 uuid 模块 - 唯一标识符
概念:UUID 的用途
UUID(Universally Unique Identifier)是128位的唯一标识符,用于在分布式系统中生成不会冲突的唯一ID。Python 的 uuid 模块支持多种 UUID 生成算法。
生成 UUID
python
import uuid
# UUID1: 基于时间戳和MAC地址
uid1 = uuid.uuid1()
print(uid1) # 6e5bc7a2-1234-11eb-9c7f-54e1ad0c3c4b
# UUID3: 基于命名空间和MD5
uid3 = uuid.uuid3(uuid.NAMESPACE_DNS, "example.com")
print(uid3) # 9a2c4f3e-1a2b-3c4d-5e6f-7a8b9c0d1e2f
# UUID4: 随机 UUID(最常用)
uid4 = uuid.uuid4()
print(uid4) # 7c4a8d09-e5f2-4b8a-9d3f-1e2d3c4b5a6d
# UUID5: 基于命名空间和SHA-1
uid5 = uuid.uuid5(uuid.NAMESPACE_DNS, "example.com")
print(uid5)
# 格式化
print(str(uid4)) # 带连字符
print(uid4.hex) # 不带连字符
print(uid4.int) # 整数形式
print(uid4.bytes) # 16字节形式
实际应用
python
import uuid
# 生成唯一文件名
def save_uploaded_file(uploaded_file):
ext = uploaded_file.name.split(".")[-1]
filename = f"{uuid.uuid4()}.{ext}"
# 保存到磁盘
return filename
# 生成唯一ID用于缓存
cache_key = f"user:{uuid.uuid4()}"
3.14 hashlib 模块 - 哈希算法
概念:哈希算法的作用
哈希算法将任意长度的数据转换为固定长度的"指纹"字符串,常用于数据完整性校验、密码存储、数字签名等。Python 的 hashlib 支持 MD5、SHA-1、SHA-256 等常用算法。
基础使用
python
import hashlib
# 创建哈希对象
h = hashlib.sha256()
h.update(b"Hello")
print(h.hexdigest()) # 64位十六进制字符串
# 支持的算法
print(hashlib.algorithms_available)
print(hashlib.algorithms_guaranteed)
# 常用算法
md5 = hashlib.md5()
sha1 = hashlib.sha1()
sha256 = hashlib.sha256()
sha512 = hashlib.sha512()
计算文件哈希
python
import hashlib
def file_hash(filepath, algorithm="sha256"):
h = hashlib.new(algorithm)
with open(filepath, "rb") as f:
while chunk := f.read(8192):
h.update(chunk)
return h.hexdigest()
# 计算大文件
print(file_hash("large_file.zip", "sha256"))
# 验证文件完整性
original = "abc123..."
downloaded = file_hash("downloaded.zip")
if original == downloaded:
print("文件完整")
密码处理
python
import hashlib
import secrets
# 不推荐:简单哈希(可被彩虹表攻击)
h = hashlib.md5(b"password123").hexdigest()
# 推荐:加盐哈希
salt = secrets.token_hex(16)
password = "password123"
h = hashlib.pbkdf2_hmac("sha256", password.encode(), salt.encode(), 100000)
# bcrypt(需要安装):专业密码哈希
# import bcrypt
# hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt())
# bcrypt.checkpw(password.encode(), hashed)
3.15 csv 模块 - CSV 文件处理
概念:CSV 格式
CSV(Comma-Separated Values)是一种简单的表格数据格式,用逗号分隔值。Python 的 csv 模块提供了读写 CSV 文件的功能,支持自定义分隔符和引用规则。
读取 CSV
python
import csv
# 读取为列表
with open("data.csv", "r", encoding="utf-8", newline="") as f:
reader = csv.reader(f)
for row in reader:
print(row)
# 读取为字典
with open("data.csv", "r", encoding="utf-8", newline="") as f:
reader = csv.DictReader(f)
for row in reader:
print(row["name"], row["age"])
# 指定分隔符
reader = csv.reader(f, delimiter=";")
写入 CSV
python
import csv
# 写入列表
with open("output.csv", "w", encoding="utf-8", newline="") as f:
writer = csv.writer(f)
writer.writerow(["name", "age", "city"]) # 写入一行
writer.writerows([
["Alice", 25, "Beijing"],
["Bob", 30, "Shanghai"],
])
# 写入字典
with open("output.csv", "w", encoding="utf-8", newline="") as f:
fieldnames = ["name", "age", "city"]
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerow({"name": "Alice", "age": 25, "city": "Beijing"})
处理复杂数据
python
import csv
# 读取含引号的字段
with open("data.csv", "r", encoding="utf-8", newline="") as f:
reader = csv.reader(f, quotechar='"', quoting=csv.QUOTE_ALL)
# quoting 选项: QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE
# 方言(预定义格式)
with open("data.tsv", "r", encoding="utf-8", newline="") as f:
reader = csv.DictReader(f, dialect="excel-tab")
3.16 configparser 模块 - 配置文件
概念:INI 文件格式
INI 是 Windows 系统中常见的配置文件格式,由节(section)和键值对(key=value)组成。Python 的 configparser 模块用于读取和写入 INI 格式配置文件。
读取配置
python
import configparser
config = configparser.ConfigParser()
# 从文件读取
config.read("config.ini", encoding="utf-8")
# 读取值
print(config["DEFAULT"]["app_name"])
print(config["database"]["host"])
print(config.getint("database", "port")) # 转换为整数
print(config.getboolean("settings", "debug"))
# 获取所有节
print(config.sections())
# 检查节/键是否存在
if "database" in config:
print("database 节存在")
创建和写入配置
python
import configparser
config = configparser.ConfigParser()
config["DEFAULT"] = {
"app_name": "MyApp",
"version": "1.0.0"
}
config["database"] = {
"host": "localhost",
"port": 3306,
"username": "root",
"password": "123456"
}
config["settings"] = {
"debug": True,
"max_connections": 100
}
# 写入文件
with open("config.ini", "w", encoding="utf-8") as f:
config.write(f)
配置文件示例
ini
[DEFAULT]
app_name = MyApp
version = 1.0.0
[database]
host = localhost
port = 3306
username = root
password = secret
[settings]
debug = true
max_connections = 100
3.17 copy 模块 - 对象拷贝
概念:浅拷贝 vs 深拷贝
- 浅拷贝:创建一个新对象,但只拷贝原对象中的引用(对于嵌套对象,拷贝的是引用而非对象本身)
- 深拷贝:递归拷贝所有嵌套对象,创建完全独立的新对象
python
import copy
# 浅拷贝
original = [[1, 2, 3], [4, 5, 6]]
shallow = copy.copy(original)
# 深拷贝
deep = copy.deepcopy(original)
# 修改原始数据
original[0][0] = 999
print(original) # [[999, 2, 3], [4, 5, 6]]
print(shallow) # [[999, 2, 3], [4, 5, 6]](浅拷贝受影响)
print(deep) # [[1, 2, 3], [4, 5, 6]](深拷贝不受影响)
# 浅拷贝的其他方式
lst = [1, 2, 3]
lst_copy = lst[:] # 切片
lst_copy = list(lst) # 构造函数
import copy
lst_copy = copy.copy(lst)
深拷贝的实际应用
python
import copy
# 拷贝复杂对象
config = {
"database": {
"host": "localhost",
"port": 3306,
"settings": {"timeout": 30}
},
"cache": {
"host": "redis.local",
"port": 6379
}
}
# 备份配置
backup = copy.deepcopy(config)
# 修改原始配置
config["database"]["host"] = "production.db.com"
print(config["database"]["host"]) # production.db.com
print(backup["database"]["host"]) # localhost(备份不变)
3.18 pprint 模块 - 格式化打印
概念:pprint 的作用
pprint(Pretty Print)模块提供了更美观的打印输出功能,比 print 更适合打印复杂的数据结构,如嵌套字典、列表等,可以自动调整宽度和缩进。
基础使用
python
from pprint import pprint
data = {
"students": [
{"name": "Alice", "scores": [90, 85, 88]},
{"name": "Bob", "scores": [92, 80, 95]},
],
"class": "A",
"year": 2024
}
pprint(data)
# 打印到字符串
from pprint import pformat
string = pformat(data)
控制输出格式
python
from pprint import pprint
data = {"key": "value" * 50}
# 控制宽度
pprint(data, width=40)
# 控制缩进
pprint(data, indent=4)
# 控制嵌套深度
pprint(data, depth=2)
# 紧凑输出
pprint(data, compact=True)
3.19 weakref 模块 - 弱引用
概念:弱引用的作用
弱引用是一种不增加对象引用计数的引用方式。当对象只被弱引用持有时,垃圾回收器可以将其回收。weakref 模块常用于实现缓存、观察者模式等,避免循环引用导致的内存泄漏。
基础使用
python
import weakref
class MyClass:
pass
obj = MyClass()
# 创建弱引用
weak_ref = weakref.ref(obj)
print(weak_ref) # <weakref at ...>
print(weak_ref()) # obj(通过弱引用访问对象)
# 对象被删除后,弱引用返回 None
del obj
print(weak_ref()) # None
WeakValueDictionary
python
import weakref
# 值是弱引用的字典
class Student:
def __init__(self, name):
self.name = name
def __repr__(self):
return f"Student({self.name!r})"
students = weakref.WeakValueDictionary()
s1 = Student("Alice")
s2 = Student("Bob")
students["a"] = s1
students["b"] = s2
print(students["a"]) # Student('Alice')
# 删除 s1 后,字典中的引用自动消失
del s1
import gc
gc.collect()
print(students.get("a")) # None
弱引用回调
python
import weakref
class MyClass:
pass
def callback(ref):
print("对象被删除了")
obj = MyClass()
weak_ref = weakref.ref(obj, callback)
del obj
# 输出: 对象被删除了
3.20 enum 模块 - 枚举类型
概念:枚举的作用
枚举是一组命名常量的集合,用于定义具有固定数量值的类型。使用枚举可以提高代码可读性和可维护性,避免使用魔法数字或字符串。
基础使用
python
from enum import Enum
# 定义枚举
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
# 访问枚举成员
print(Color.RED) # Color.RED
print(Color.RED.name) # RED
print(Color.RED.value) # 1
# 遍历枚举
for color in Color:
print(f"{color.name} = {color.value}")
# 通过值查找
print(Color(1)) # Color.RED
print(Color["RED"]) # Color.RED
枚举类型
python
from enum import Enum, IntEnum, Flag, IntFlag
# IntEnum: 整数枚举,可以像整数一样运算
class Status(IntEnum):
SUCCESS = 0
ERROR = 1
PENDING = 2
print(Status.SUCCESS + 1) # 3
# Flag: 位标志枚举
class Permission(Flag):
READ = 1
WRITE = 2
EXECUTE = 4
print(Permission.READ | Permission.WRITE) # Permission.READ|WRITE
print(Permission.READ & Permission.WRITE) # Permission.0
# IntFlag: 整数位标志
class Mode(IntFlag):
R = 4
W = 2
X = 1
print(Mode.R | Mode.W) # 6
# auto: 自动赋值
from enum import auto
class Weekday(Enum):
MONDAY = auto()
TUESDAY = auto()
WEDNESDAY = auto()
枚举方法
python
from enum import Enum, auto
class Color(Enum):
RED = auto()
GREEN = auto()
BLUE = auto()
# 检查成员身份
c = Color.RED
print(isinstance(c, Color)) # True
print(c in Color) # True
# 比较
print(Color.RED == Color.GREEN) # False
print(Color.RED is Color.RED) # True
3.21 tempfile 模块 - 临时文件
概念:临时文件的作用
tempfile 模块用于创建临时文件和目录,避免手动清理。它会自动生成唯一的文件名,支持上下文管理器,确保使用后自动删除。
临时文件
python
import tempfile
import os
# 创建临时文件
with tempfile.NamedTemporaryFile(mode="w", delete=True, suffix=".txt", dir=".") as f:
f.write("临时内容")
print(f.name) # 临时文件路径
# 文件自动删除
# 创建不删除的临时文件(用于调试)
with tempfile.NamedTemporaryFile(delete=False) as f:
f.write("内容")
temp_path = f.name
print(temp_path)
os.unlink(temp_path) # 手动删除
# 获取临时目录
print(tempfile.gettempdir()) # 系统临时目录
# 临时文件句柄
temp = tempfile.TemporaryFile(mode="w+")
temp.write("hello")
temp.seek(0)
print(temp.read())
temp.close()
临时目录
python
import tempfile
import shutil
# 创建临时目录
with tempfile.TemporaryDirectory() as tmpdir:
print(f"临时目录: {tmpdir}")
# 在目录中创建文件
with open(os.path.join(tmpdir, "test.txt"), "w") as f:
f.write("内容")
# 目录自动删除
# 创建不删除的临时目录
tmpdir = tempfile.mkdtemp()
print(f"手动删除: {tmpdir}")
shutil.rmtree(tmpdir)
3.22 glob 模块 - 文件名模式匹配
概念:glob 的作用
glob 模块用于根据通配符模式匹配文件名,类似于命令行中的 ls *.py。它比正则表达式更简单直观,适合快速查找文件。
基础使用
python
import glob
# 匹配当前目录的 py 文件
for f in glob.glob("*.py"):
print(f)
# 匹配子目录
for f in glob.glob("**/*.py", recursive=True):
print(f)
# 匹配多个模式
for f in glob.glob(["*.py", "*.md"]):
print(f)
# 通配符
# * 匹配任意字符
# ? 匹配单个字符
# [] 匹配字符集合
# 递归搜索
for f in glob.glob("**/*", recursive=True):
print(f)
pathlib 方式
python
from pathlib import Path
# 使用 pathlib 的 glob
for f in Path(".").glob("*.py"):
print(f)
# 递归 glob
for f in Path(".").rglob("*.py"):
print(f)
# iglob(返回迭代器,不一次性加载)
for f in Path(".").rglob("*.py"):
print(f)
3.23 base64 模块 - Base64 编码
概念:Base64 的用途
Base64 是一种将二进制数据编码为可打印 ASCII 字符的格式,常用于在 JSON 中传输二进制数据、邮件附件、URL 参数等场景。
基础使用
python
import base64
# 字符串编码
message = "Hello, World!"
encoded = base64.b64encode(message.encode())
print(encoded) # b'SGVsbG8sIFdvcmxkISc='
# 解码
decoded = base64.b64decode(encoded)
print(decoded.decode()) # Hello, World!
# 二进制数据编码
with open("image.png", "rb") as f:
data = f.read()
encoded = base64.b64encode(data)
print(f"data:image/png;base64,{encoded.decode()}")
URL 安全 Base64
python
import base64
# URL 安全编码(替换 +/ 为 -_)
encoded = base64.urlsafe_b64encode(b"Hello+World/")
print(encoded) # b'SGVsbG8rV29ybGQv'
# 解码
decoded = base64.urlsafe_b64decode(encoded)
print(decoded) # b'Hello+World/'
3.24 secrets 模块 - 安全随机数
概念:secrets 的用途
secrets 模块用于生成密码学安全的随机数,适合创建令牌、密码、API 密钥等。在 Python 3.6+ 推荐使用 secrets 替代 random 模块的安全用途。
生成令牌
python
import secrets
# 生成随机字节
token = secrets.token_bytes(32)
print(token.hex())
# 生成十六进制字符串
token = secrets.token_hex(32)
print(token)
# 生成 URL 安全令牌
token = secrets.token_urlsafe(32)
print(token)
安全随机数
python
import secrets
# 随机整数(在范围内)
num = secrets.randbelow(100) # 0-99
print(num)
# 随机选择
choices = ["apple", "banana", "cherry", "date"]
selected = secrets.choice(choices)
print(selected)
# 生成密码
import string
password = "".join(
secrets.choice(string.ascii_letters + string.digits)
for _ in range(16)
)
print(password)
3.25 string 模块 - 字符串工具
概念:string 模块的内容
string 模块提供了各种字符串常量和模板类,包括字母表、数字、标点符号等常量,以及用于格式化替换的 Template 类。
字符串常量
python
import string
# 字母
print(string.ascii_letters) # abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
print(string.ascii_lowercase) # abcdefghijklmnopqrstuvwxyz
print(string.ascii_uppercase) # ABCDEFGHIJKLMNOPQRSTUVWXYZ
# 数字和标点
print(string.digits) # 0123456789
print(string.hexdigits) # 0123456789abcdefABCDEF
print(string.octdigits) # 01234567
print(string.punctuation) # !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
print(string.whitespace) # 空格、tab、换行等
print(string.printable) # 可打印字符
格式化字符串
python
import string
# Template:简化字符串替换
template = string.Template("$name 是 $action 的 $who")
result = template.substitute(name="Alice", action="吃", who="苹果")
print(result) # Alice 是 吃 的 苹果
# 安全替换(缺少的键用默认值)
template = string.Template("$name 喜欢 $item")
result = template.safe_substitute(name="Bob", item="香蕉")
print(result) # Bob 喜欢 香蕉
# 使用字典
data = {"name": "Charlie", "action": "玩", "target": "游戏"}
result = template.substitute(data)
print(result) # Charlie 喜欢 游戏
Formatter
python
import string
# 高级字符串格式化
formatter = string.Formatter()
# 格式化字典
data = {"name": "Alice", "age": 25}
result = formatter.vformat("{name} is {age}", [], data)
print(result)
# 自定义格式化
class MyFormat(string.Formatter):
def format_field(self, value, format_spec):
if format_spec == "reverse":
return str(value)[::-1]
return super().format_field(value, format_spec)
fmt = MyFormat()
print(fmt.format("{name} reversed: {name:reverse}", name="hello"))