
你有没有过这样的经历?
为了一个小功能,写了半天代码,结果发现Python早就给你准备好了。
说实话,我之前也经常这样。
直到我发现Python标准库简直就是个宝库。
今天给大家整理了20个超好用的内置模块,每个都配有详细代码示例,掌握它们,你的代码会变得更加精简、专业。
别再用print调试了!
logging模块提供了灵活的日志记录功能,是生产环境监控的不二之选。
它可以帮你实现日志分级、输出到文件、格式化等功能。
什么时候用?
示例1:基本配置和使用
import logging
# 基本配置:将INFO及以上级别日志输出到控制台
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger('MyApp')
logger.info('程序启动')
logger.warning('这是一个警告')
logger.error('发生了一个错误')
# 输出结果:
# 2024-01-01 10:00:00 - MyApp - INFO - 程序启动
# 2024-01-01 10:00:00 - MyApp - WARNING - 这是一个警告
# 2024-01-01 10:00:00 - MyApp - ERROR - 发生了一个错误示例2:同时输出到文件和控制台
import logging
# 创建logger
logger = logging.getLogger('MyApp')
logger.setLevel(logging.INFO)
# 创建文件处理器
file_handler = logging.FileHandler('app.log')
file_handler.setLevel(logging.WARNING)
# 创建控制台处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
# 创建格式化器
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)
# 添加处理器到logger
logger.addHandler(file_handler)
logger.addHandler(console_handler)
logger.info('这条会显示在控制台')
logger.warning('这条会同时显示在控制台和写入文件')
logger.error('这条会同时显示在控制台和写入文件')示例3:异常追踪
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger('ErrorDemo')
def divide(a, b):
try:
result = a / b
logger.info(f'计算结果: {result}')
return result
except Exception as e:
# exc_info=True 会自动记录异常堆栈
logger.error(f'除法失败: {e}', exc_info=True)
divide(10, 2) # 正常
divide(10, 0) # 会记录完整的异常堆栈信息还在用字符串拼接路径吗?
pathlib提供了面向对象的API来处理文件系统路径。
它让你告别繁琐的os.path.join,跨平台兼容性更好。
示例1:路径创建和拼接
from pathlib import Path
# 创建路径对象
project_root = Path.home() / 'projects' / 'my_app'
config_file = project_root / 'config' / 'settings.yaml'
print(f'项目路径: {project_root}')
print(f'配置文件: {config_file}')
# 输出结果:
# 项目路径: /Users/username/projects/my_app
# 配置文件: /Users/username/projects/my_app/config/settings.yaml示例2:路径检查和文件信息
from pathlib import Path
file_path = Path('example.txt')
# 检查文件是否存在
if file_path.exists():
print(f'文件存在')
# 检查是否为文件
if file_path.is_file():
print(f'是文件')
# 获取文件信息
stat = file_path.stat()
print(f'文件大小: {stat.st_size} 字节')
print(f'最后修改时间: {stat.st_mtime}')
# 获取文件名和扩展名
print(f'文件名: {file_path.name}')
print(f'不带扩展名: {file_path.stem}')
print(f'扩展名: {file_path.suffix}')
else:
print('文件不存在')示例3:目录遍历
from pathlib import Path
# 获取当前目录下的所有Python文件
current_dir = Path('.')
# 只查找当前目录
py_files = list(current_dir.glob('*.py'))
print(f'当前目录的Python文件: {py_files}')
# 递归查找所有子目录
all_py_files = list(current_dir.rglob('*.py'))
print(f'所有Python文件数量: {len(all_py_files)}')
# 遍历并显示相对路径
for py_file in current_dir.rglob('*.py')[:5]:
print(f'相对路径: {py_file.relative_to(current_dir)}')示例4:文件读写和创建目录
from pathlib import Path
# 创建目录(包括父目录)
log_dir = Path('logs') / '2024' / '01'
log_dir.mkdir(parents=True, exist_ok=True)
# 写入文件
log_file = log_dir / 'app.log'
log_file.write_text('这是一条日志\n', encoding='utf-8')
# 追加内容
log_file.write_text('这是第二条日志\n', encoding='utf-8', append=True)
# 读取文件
content = log_file.read_text(encoding='utf-8')
print(f'文件内容:\n{content}')想让你的脚本支持命令行参数?
argparse帮你轻松创建专业、用户友好的命令行界面。
示例1:基本用法
import argparse
# 创建解析器
parser = argparse.ArgumentParser(description='一个简单的文件处理工具')
# 添加参数
parser.add_argument('filename', help='要处理的文件名')
# 解析参数
args = parser.parse_args()
print(f'处理的文件: {args.filename}')
# 运行: python script.py data.txt
# 输出: 处理的文件: data.txt示例2:可选参数和默认值
import argparse
parser = argparse.ArgumentParser(description='数据处理脚本')
# 必需参数
parser.add_argument('input', help='输入文件路径')
# 可选参数(短选项和长选项)
parser.add_argument('-o', '--output', default='output.txt',
help='输出文件路径(默认: output.txt)')
# 带类型检查的参数
parser.add_argument('--count', type=int, default=1,
help='处理次数(默认: 1)')
# 开关型参数
parser.add_argument('-v', '--verbose', action='store_true',
help='显示详细信息')
args = parser.parse_args()
print(f'输入: {args.input}')
print(f'输出: {args.output}')
print(f'次数: {args.count}')
print(f'详细模式: {args.verbose}')
# 运行: python script.py input.txt -o result.txt --count 5 -v示例3:互斥参数和选择参数
import argparse
parser = argparse.ArgumentParser(description='文件转换工具')
# 互斥参数组(只能选一个)
group = parser.add_mutually_exclusive_group()
group.add_argument('--compress', action='store_true',
help='压缩文件')
group.add_argument('--decompress', action='store_true',
help='解压文件')
# 限制选择范围的参数
parser.add_argument('--format', choices=['zip', 'tar', 'gz'],
default='zip',
help='压缩格式(zip/tar/gz)')
args = parser.parse_args()
if args.compress:
print(f'压缩文件,格式: {args.format}')
elif args.decompress:
print(f'解压文件,格式: {args.format}')
else:
print('请指定 --compress 或 --decompress')示例4:位置参数列表
import argparse
parser = argparse.ArgumentParser(description='批量处理文件')
# nargs='+' 表示至少一个参数
# nargs='*' 表示零个或多个参数
parser.add_argument('files', nargs='+', help='要处理的文件列表')
parser.add_argument('-r', '--reverse', action='store_true',
help='反向处理')
args = parser.parse_args()
print(f'要处理 {len(args.files)} 个文件:')
for i, file in enumerate(args.files, 1):
print(f' {i}. {file}')
if args.reverse:
print('处理顺序: 反向')
# 运行: python script.py file1.txt file2.txt file3.txt -rJSON是现代应用中最常见的数据交换格式。
json模块帮你轻松处理JSON数据的编码和解码。
示例1:序列化和反序列化
import json
# Python对象
data = {
'name': '张三',
'age': 25,
'city': '北京',
'skills': ['Python', 'JavaScript', 'SQL']
}
# 序列化为JSON字符串
json_str = json.dumps(data, indent=2, ensure_ascii=False)
print('JSON字符串:')
print(json_str)
# 反序列化为Python对象
loaded_data = json.loads(json_str)
print(f'\n加载的数据: {loaded_data}')示例2:读写JSON文件
import json
from pathlib import Path
# 准备数据
config = {
'app_name': 'MyApp',
'version': '1.0.0',
'settings': {
'debug': True,
'max_users': 100
}
}
# 写入JSON文件
config_file = Path('config.json')
config_file.write_text(
json.dumps(config, indent=2, ensure_ascii=False),
encoding='utf-8'
)
print('配置文件已保存')
# 读取JSON文件
if config_file.exists():
loaded_config = json.loads(config_file.read_text(encoding='utf-8'))
print(f'应用名称: {loaded_config["app_name"]}')
print(f'调试模式: {loaded_config["settings"]["debug"]}')示例3:处理特殊数据类型
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 = {
'event': '会议',
'time': datetime(2024, 1, 1, 10, 0),
'duration': 2.5
}
# 使用自定义编码器
json_str = json.dumps(data, cls=DateTimeEncoder, ensure_ascii=False)
print(json_str)示例4:美化输出和排序
import json
data = {
'z': 1,
'a': 2,
'm': 3
}
# 默认顺序
print('默认顺序:')
print(json.dumps(data))
# 按键排序
print('\n按键排序:')
print(json.dumps(data, sort_keys=True, indent=2))时间处理从来都不是件轻松的事。
datetime模块提供了日期、时间、时间间隔等相关类。
示例1:获取当前时间
from datetime import datetime, date, time
# 获取当前日期时间
now = datetime.now()
print(f'当前时间: {now}')
print(f'年: {now.year}, 月: {now.month}, 日: {now.day}')
# 只获取日期
today = date.today()
print(f'今天的日期: {today}')
# 创建特定时间
specific_time = time(14, 30, 0)
print(f'特定时间: {specific_time}')示例2:时间格式化和解析
from datetime import datetime
# 创建日期时间
dt = datetime(2024, 1, 1, 14, 30)
# 格式化为字符串
formatted = dt.strftime('%Y年%m月%d日 %H:%M:%S')
print(f'格式化后: {formatted}')
# 常用格式符号
print(dt.strftime('%Y-%m-%d')) # 2024-01-01
print(dt.strftime('%A')) # Monday
print(dt.strftime('%a')) # Mon
# 解析字符串为日期时间
date_str = '2024-01-01 14:30:00'
parsed = datetime.strptime(date_str, '%Y-%m-%d %H:%M:%S')
print(f'解析结果: {parsed}')示例3:时间计算
from datetime import datetime, timedelta
# 创建时间
dt = datetime(2024, 1, 1, 10, 0)
# 时间差
delta = timedelta(days=7, hours=3, minutes=30)
# 未来时间
future = dt + delta
print(f'未来时间: {future}')
# 过去时间
past = dt - delta
print(f'过去时间: {past}')
# 计算两个时间的差值
dt1 = datetime(2024, 1, 1)
dt2 = datetime(2024, 1, 10)
diff = dt2 - dt1
print(f'相差天数: {diff.days}')
print(f'总秒数: {diff.total_seconds()}')示例4:比较和判断
from datetime import datetime
# 创建时间
dt1 = datetime(2024, 1, 1)
dt2 = datetime(2024, 1, 10)
now = datetime.now()
# 比较
print(f'dt1 < dt2: {dt1 < dt2}')
print(f'now > dt1: {now > dt1}')
# 判断是否在范围内
start = datetime(2024, 1, 1)
end = datetime(2024, 12, 31)
check_date = datetime(2024, 6, 1)
is_in_range = start <= check_date <= end
print(f'是否在2024年内: {is_in_range}')
# 获取星期几
today = datetime.now()
weekdays = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
print(f'今天是: {weekdays[today.weekday()}')这个模块提供了很多好用的特殊容器类型。
示例1:defaultdict - 默认值字典
from collections import defaultdict
# 普通字典的问题
normal_dict = {}
# normal_dict['key'] # KeyError
# defaultdict 自动提供默认值
dd = defaultdict(list)
dd['fruits'].append('apple')
dd['fruits'].append('banana')
dd['vegetables'].append('carrot')
print(dict(dd))
# 输出: {'fruits': ['apple', 'banana'], 'vegetables': ['carrot']}示例2:Counter - 计数器
from collections import Counter
# 统计元素出现次数
words = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
counter = Counter(words)
print(f'计数结果: {counter}')
# 输出: Counter({'apple': 3, 'banana': 2, 'orange': 1})
# 最常见的元素
print(f'最常见的2个: {counter.most_common(2)}')
# 字符串统计
text = 'hello world'
char_counter = Counter(text)
print(f'字符统计: {char_counter}')
# 计算两个Counter的差
c1 = Counter(['a', 'b', 'a', 'c'])
c2 = Counter(['a', 'b'])
diff = c1 - c2
print(f'差集: {diff}')示例3:deque - 双端队列
from collections import deque
# 创建双端队列
dq = deque([1, 2, 3])
# 两端操作
dq.append(4) # 右端添加
dq.appendleft(0) # 左端添加
print(f'队列: {list(dq)}')
# 两端移除
print(f'右端弹出: {dq.pop()}')
print(f'左端弹出: {dq.popleft()}')
# 限制长度的队列(自动移除旧元素)
recent = deque(maxlen=3)
for i in range(5):
recent.append(i)
print(f'添加{i}: {list(recent)}')
# 输出:
# 添加0: [0]
# 添加1: [0, 1]
# 添加2: [0, 1, 2]
# 添加3: [1, 2, 3]
# 添加4: [2, 3, 4]示例4:namedtuple - 命名元组
from collections import namedtuple
# 定义命名元组类型
Point = namedtuple('Point', ['x', 'y'])
Person = namedtuple('Person', ['name', 'age', 'city'])
# 创建实例
p = Point(10, 20)
print(f'坐标: ({p.x}, {p.y})')
person = Person('张三', 25, '北京')
print(f'姓名: {person.name}')
print(f'年龄: {person.age}')
# 可以像元组一样操作
print(f'第一个元素: {person[0]}')
# 解包
name, age, city = person
print(f'解包结果: {name}, {age}, {city}')
# _make 方法从可迭代对象创建
person2 = Person._make(['李四', 30, '上海'])
print(f'person2: {person2}')处理数据流?找itertools就对了。
示例1:无限序列
import itertools
# count - 无限计数器
counter = itertools.count(start=10, step=2)
print('计数器:')
for i in range(5):
print(next(counter))
# cycle - 无限循环
cycler = itertools.cycle(['A', 'B', 'C'])
print('\n循环:')
for i in range(7):
print(next(cycler))
# repeat - 重复元素
repeater = itertools.repeat('hello', times=3)
print('\n重复:')
for item in repeater:
print(item)示例2:连接多个迭代器
import itertools
# chain - 连接多个可迭代对象
chained = itertools.chain([1, 2], 'AB', range(3))
print('连接结果:', list(chained))
# chain.from_iterable - 连接嵌套的可迭代对象
nested = [[1, 2], [3, 4], [5]]
flattened = list(itertools.chain.from_iterable(nested))
print('展平结果:', flattened)示例3:分组操作
import itertools
# groupby - 分组(需要先排序)
data = [
('A', 1), ('B', 2), ('A', 3),
('B', 4), ('A', 5)
]
# 按第一个元素分组
data.sort(key=lambda x: x[0])
for key, group in itertools.groupby(data, key=lambda x: x[0]):
print(f'\n分组 {key}:')
for item in group:
print(f' {item}')示例4:组合和排列
import itertools
# combinations - 组合(顺序无关)
print('ABC的组合数C(3,2):')
for combo in itertools.combinations('ABC', 2):
print(f' {combo}')
# combinations_with_replacement - 可重复组合
print('\n可重复组合:')
for combo in itertools.combinations_with_replacement('AB', 2):
print(f' {combo}')
# permutations - 排列(顺序相关)
print('\nAB的排列数P(2,2):')
for perm in itertools.permutations('AB', 2):
print(f' {perm}')
# product - 笛卡尔积
print('\nAB × 12的笛卡尔积:')
for prod in itertools.product('AB', '12'):
print(f' {prod}')操作函数的函数?那就是functools。
示例1:lru_cache - 函数缓存
import time
from functools import lru_cache
# 普通函数
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
# 使用缓存装饰器
@lru_cache(maxsize=32)
def fibonacci_cached(n):
if n <= 1:
return n
return fibonacci_cached(n-1) + fibonacci_cached(n-2)
# 测试性能
start = time.time()
result1 = fibonacci(35)
time1 = time.time() - start
print(f'未缓存: {result1}, 耗时: {time1:.4f}秒')
start = time.time()
result2 = fibonacci_cached(35)
time2 = time.time() - start
print(f'已缓存: {result2}, 耗时: {time2:.4f}秒')
# 查看缓存信息
print(f'缓存信息: {fibonacci_cached.cache_info()}')示例2:partial - 偏函数
from functools import partial
# 原始函数
def power(base, exponent):
return base ** exponent
# 创建平方函数
square = partial(power, exponent=2)
print(f'5的平方: {square(5)}')
# 创建立方函数
cube = partial(power, exponent=3)
print(f'5的立方: {cube(5)}')
# 另一个例子
def greet(name, greeting, punctuation):
return f'{greeting}, {name}{punctuation}'
# 创建固定的问候函数
say_hello = partial(greet, greeting='你好', punctuation='!')
print(say_hello('张三'))
say_hi = partial(greet, greeting='Hi', punctuation='.')
print(say_hi('Alice'))示例3:wraps - 装饰器保留元信息
import time
from functools import wraps
# 不使用wraps的装饰器
def decorator_without_waps(func):
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
# 使用wraps的装饰器
def timer(func):
@wraps(func) # 保留原函数的元信息
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f'{func.__name__} 耗时: {end-start:.4f}秒')
return result
return wrapper
@timer
def add(a, b):
'''加法函数'''
return a + b
print(f'函数名: {add.__name__}')
print(f'文档字符串: {add.__doc__}')
result = add(3, 5)想用多线程/多进程提升性能?
这个模块提供了ThreadPoolExecutor和ProcessPoolExecutor。
示例1:ThreadPoolExecutor - I/O密集型任务
from concurrent.futures import ThreadPoolExecutor
import time
def task(name, delay):
print(f'{name} 开始')
time.sleep(delay)
print(f'{name} 完成')
return f'{name}的结果'
# 使用线程池
with ThreadPoolExecutor(max_workers=3) as executor:
# 提交任务
future1 = executor.submit(task, '任务1', 2)
future2 = executor.submit(task, '任务2', 1)
future3 = executor.submit(task, '任务3', 3)
# 获取结果
print(f'任务1结果: {future1.result()}')
print(f'任务2结果: {future2.result()}')
print(f'任务3结果: {future3.result()}')示例2:ProcessPoolExecutor - CPU密集型任务
from concurrent.futures import ProcessPoolExecutor
import time
def compute(n):
"""CPU密集型计算"""
total = 0
for i in range(n):
total += i ** 2
return total
# 使用进程池
with ProcessPoolExecutor(max_workers=2) as executor:
numbers = [100000, 200000, 300000]
# 提交任务
futures = [executor.submit(compute, n) for n in numbers]
# 获取结果
for future, n in zip(futures, numbers):
result = future.result()
print(f'计算{n}: 结果={result}')示例3:map方法 - 批量处理
from concurrent.futures import ThreadPoolExecutor
def process_item(item):
return item * 2
items = [1, 2, 3, 4, 5]
# 使用map批量处理
with ThreadPoolExecutor(max_workers=3) as executor:
results = list(executor.map(process_item, items))
print(f'处理结果: {results}')示例4:as_completed - 按完成顺序获取结果
from concurrent.futures import ThreadPoolExecutor, as_completed
import random
import time
def random_task(name):
delay = random.uniform(0.5, 2.0)
time.sleep(delay)
return f'{name} 耗时 {delay:.2f}秒'
tasks = ['任务A', '任务B', '任务C', '任务D']
with ThreadPoolExecutor(max_workers=3) as executor:
futures = {executor.submit(random_task, task): task for task in tasks}
# 按完成顺序获取结果
for future in as_completed(futures):
task = futures[future]
try:
result = future.result()
print(f'{task} 完成: {result}')
except Exception as e:
print(f'{task} 失败: {e}')Python 3.7+的福音!
一个装饰器自动生成__init__、__repr__、__eq__等方法。
示例1:基本用法
from dataclasses import dataclass
@dataclass
class Point:
x: float
y: float
# 自动生成构造函数
p = Point(3.0, 4.0)
print(f'点: {p}')
print(f'x坐标: {p.x}, y坐标: {p.y}')
# 自动生成__eq__方法
p1 = Point(1, 2)
p2 = Point(1, 2)
p3 = Point(2, 3)
print(f'p1 == p2: {p1 == p2}')
print(f'p1 == p3: {p1 == p3}')示例2:默认值和可变默认值
from dataclasses import dataclass, field
from typing import List
@dataclass
class Product:
name: str
price: float
# 简单默认值
in_stock: bool = True
# 可变默认值需要用field
tags: List[str] = field(default_factory=list)
# 不在__repr__中显示
_internal_id: str = field(default='', repr=False)
p1 = Product(name='笔记本', price=5999.99, tags=['电子', '电脑'])
p2 = Product(name='鼠标', price=99.5)
print(p1)
print(p2)
p2.tags.append('外设')
print(p2)示例3:不可变数据类和排序
from dataclasses import dataclass
@dataclass(frozen=True, order=True)
class Student:
name: str
age: int
score: float
s1 = Student('张三', 18, 85.5)
s2 = Student('李四', 19, 92.0)
s3 = Student('王五', 18, 88.0)
# frozen=True 不可修改
# s1.age = 19 # 会报错
# order=True 自动生成比较方法
print(f'按年龄排序: {sorted([s1, s2, s3])}')
# 哈希化(因为不可变)
students_set = {s1, s2, s3}
print(f'集合: {students_set}')示例4:转换为字典和元组
from dataclasses import dataclass, asdict, astuple
@dataclass
class Person:
name: str
age: int
city: str
person = Person('Alice', 25, 'Beijing')
# 转换为字典
person_dict = asdict(person)
print(f'字典: {person_dict}')
# 转换为元组
person_tuple = astuple(person)
print(f'元组: {person_tuple}')
# JSON序列化
import json
json_str = json.dumps(asdict(person), ensure_ascii=False)
print(f'JSON: {json_str}')pathlib的完美搭档。
shutil提供了对文件和目录集合进行高级操作的接口。
示例1:文件复制
import shutil
from pathlib import Path
# 创建测试文件
src_file = Path('source.txt')
src_file.write_text('这是源文件内容')
# 复制文件
dst_file = Path('destination.txt')
shutil.copy(src_file, dst_file)
print(f'源文件: {src_file.exists()}')
print(f'目标文件: {dst_file.exists()}')
print(f'内容: {dst_file.read_text()}')
# 复制文件并保留元数据
shutil.copy2(src_file, Path('destination_meta.txt'))示例2:目录复制
import shutil
from pathlib import Path
# 创建源目录
src_dir = Path('source_dir')
src_dir.mkdir(exist_ok=True)
(src_dir / 'file1.txt').write_text('文件1')
(src_dir / 'file2.txt').write_text('文件2')
# 递归复制目录
dst_dir = Path('destination_dir')
shutil.copytree(src_dir, dst_dir)
print('目标目录内容:')
for item in dst_dir.iterdir():
print(f' {item.name}')示例3:文件和目录移动
import shutil
from pathlib import Path
# 创建文件
file1 = Path('file1.txt')
file1.write_text('内容1')
file2 = Path('file2.txt')
file2.write_text('内容2')
# 移动文件
shutil.move('file1.txt', 'moved_file.txt')
# 移动目录
dir1 = Path('dir1')
dir1.mkdir(exist_ok=True)
(dir1 / 'file.txt').write_text('内容')
shutil.move('dir1', 'moved_dir')
print(f'moved_dir存在: {Path("moved_dir").exists()}')示例4:删除和归档
import shutil
from pathlib import Path
# 创建测试目录
test_dir = Path('test_dir')
test_dir.mkdir(exist_ok=True)
(test_dir / 'file1.txt').write_text('内容1')
(test_dir / 'file2.txt').write_text('内容2')
# 递归删除目录
if test_dir.exists():
shutil.rmtree(test_dir)
print(f'目录已删除: {not test_dir.exists()}')
# 创建归档
archive_dir = Path('archive')
archive_dir.mkdir(exist_ok=True)
(archive_dir / 'file1.txt').write_text('内容1')
(archive_dir / 'file2.txt').write_text('内容2')
# 创建zip归档
shutil.make_archive('my_backup', 'zip', root_dir=str(archive_dir))
print('zip归档已创建')
# 创建tar归档
shutil.make_archive('my_backup_tar', 'tar', root_dir=str(archive_dir))
print('tar归档已创建')Python是动态语言,但也可以有类型提示!
typing模块支持为变量、函数参数和返回值添加类型提示。
示例1:基本类型提示
from typing import List, Dict, Tuple, Optional, Union
def process_data(items: List[int]) -> List[int]:
"""处理整数列表"""
return [x * 2 for x in items]
def get_user_info(user_id: int) -> Dict[str, Union[str, int]]:
"""获取用户信息"""
return {
'id': user_id,
'name': 'User',
'age': 25
}
# 使用
numbers: List[int] = [1, 2, 3, 4, 5]
result = process_data(numbers)
print(f'结果: {result}')
user: Dict[str, Union[str, int]] = get_user_info(1)
print(f'用户: {user}')示例2:Optional和Union类型
from typing import Optional, Union
def find_user(user_id: int) -> Optional[Dict]:
"""查找用户,可能返回None"""
# 模拟查找
if user_id == 1:
return {'id': 1, 'name': '张三'}
return None
# Optional[Dict] 等价于 Union[Dict, None]
user1 = find_user(1)
user2 = find_user(2)
print(f'用户1: {user1}')
print(f'用户2: {user2}')
def process_value(value: Union[int, float, str]) -> str:
"""处理多种类型的值"""
return str(value)
print(f'处理int: {process_value(42)}')
print(f'处理float: {process_value(3.14)}')
print(f'处理str: {process_value("hello")}')示例3:TypedDict - 字典类型定义
from typing import TypedDict
class User(TypedDict):
"""用户类型定义"""
id: int
name: str
email: str
age: int
def send_email(user: User, subject: str) -> None:
"""发送邮件给用户"""
print(f'发送邮件给 {user["name"]} ({user["email"]})')
print(f'主题: {subject}')
# 使用
user: User = {
'id': 1,
'name': '张三',
'email': 'zhangsan@example.com',
'age': 25
}
send_email(user, '欢迎注册')示例4:Callable类型
from typing import Callable, List
def apply_operation(
items: List[int],
operation: Callable[[int], int]
) -> List[int]:
"""对列表中的每个元素应用操作"""
return [operation(item) for item in items]
# 定义操作函数
def square(x: int) -> int:
return x ** 2
def double(x: int) -> int:
return x * 2
# 使用
numbers = [1, 2, 3, 4, 5]
result1 = apply_operation(numbers, square)
print(f'平方: {result1}')
result2 = apply_operation(numbers, double)
print(f'双倍: {result2}')
# 使用lambda
result3 = apply_operation(numbers, lambda x: x + 10)
print(f'加10: {result3}')复杂的字符串匹配?正则表达式来帮忙。
re模块功能强大,用于匹配、查找、替换和分割字符串。
示例1:匹配和查找
import re
text = '联系电话: 张三 138-0013-8000, 李四 (021) 8765-4321'
# 查找所有手机号
phone_pattern = r'1[3-9]\d{9}'
phones = re.findall(phone_pattern, text)
print(f'手机号: {phones}')
# 查找第一个匹配
first_match = re.search(phone_pattern, text)
print(f'第一个匹配: {first_match.group() if first_match else "未找到"}')
# 检查是否匹配
if re.match(r'你好', '你好世界'):
print('以"你好"开头')示例2:替换和分割
import re
text = '我的电话是 138-0013-8000, 你的电话是 139-1234-5678'
# 替换手机号为****-****-****
masked = re.sub(r'1[3-9]\d{2}-\d{4}-\d{4}', '****-****-****', text)
print(f'脱敏: {masked}')
# 分割字符串
text2 = '苹果,香蕉;橘子.葡萄|西瓜'
fruits = re.split(r'[,;.|]', text2)
print(f'水果列表: {fruits}')
# 限制分割次数
fruits_limited = re.split(r'[,;.|]', text2, maxsplit=2)
print(f'限制分割: {fruits_limited}')示例3:分组和命名分组
import re
# 提取日期
date_text = '今天是 2024-01-01, 明天是 2024-01-02'
# 普通分组
pattern = r'(\d{4})-(\d{2})-(\d{2})'
matches = re.finditer(pattern, date_text)
for match in matches:
year, month, day = match.groups()
print(f'日期: {year}年{month}月{day}日')
# 命名分组
pattern_named = r'(?P\d{4})-(?P\d{2})-(?P\d{2})'
match = re.search(pattern_named, date_text)
if match:
print(f'年份: {match.group("year")}')
print(f'月份: {match.group("month")}')
print(f'日期: {match.group("day")}')示例4:预编译模式
import re
# 预编译模式(多次使用时效率更高)
email_pattern = re.compile(r'[\w.+-]+@[\w-]+\.[\w.-]+')
emails = [
'user@example.com',
'invalid-email',
'test@test.co.uk',
'another@domain.com'
]
print('邮箱验证:')
for email in emails:
if email_pattern.fullmatch(email):
print(f' ✓ {email}')
else:
print(f' ✗ {email}')这两个模块是底层工具集,通常搭配使用。
示例1:sys - 访问系统信息
import sys
# Python版本
print(f'Python版本: {sys.version}')
# 平台信息
print(f'平台: {sys.platform}')
# 命令行参数
print(f'脚本名称: {sys.argv[0]}')
print(f'参数: {sys.argv[1:]}')
# 退出程序
# sys.exit(0) # 正常退出
# sys.exit(1) # 错误退出
# 获取递归深度限制
print(f'递归深度限制: {sys.getrecursionlimit()}')
# 修改递归深度限制
sys.setrecursionlimit(2000)
print(f'新的递归深度限制: {sys.getrecursionlimit()}')示例2:sys - 标准流重定向
import sys
from io import StringIO
# 捕获print输出
old_stdout = sys.stdout
captured_output = StringIO()
# 重定向到StringIO
sys.stdout = captured_output
print('这行内容被捕获')
print('包括这行')
# 恢复标准输出
sys.stdout = old_stdout
# 获取捕获的内容
output = captured_output.getvalue()
print(f'捕获的内容:\n{output}')示例3:os - 文件和目录操作
import os
from pathlib import Path
# 当前工作目录
print(f'当前目录: {os.getcwd()}')
# 改变工作目录
# os.chdir('/tmp')
# 创建目录
test_dir = Path('test_os_dir')
test_dir.mkdir(exist_ok=True)
# 列出目录内容
print('\n目录内容:')
for item in os.listdir('.'):
if not item.startswith('.'):
print(f' {item}')
# 删除目录
if test_dir.exists():
test_dir.rmdir()
print(f'\n目录已删除')示例4:os - 环境变量和路径
import os
from pathlib import Path
# 环境变量
home = os.environ.get('HOME')
print(f'HOME目录: {home}')
# 设置环境变量
os.environ['MY_VAR'] = 'hello'
print(f'MY_VAR: {os.environ.get("MY_VAR")}')
# 路径操作
print(f'当前文件: {__file__}')
print(f'目录名: {os.path.dirname(__file__)}')
print(f'文件名: {os.path.basename(__file__)}')
# 拼接路径
full_path = os.path.join('dir1', 'dir2', 'file.txt')
print(f'拼接路径: {full_path}')
# 检查路径
print(f'文件存在: {os.path.exists(__file__)}')
print(f'是文件: {os.path.isfile(__file__)}')
print(f'是目录: {os.path.isdir(".")}')不需要安装第三方库就能处理常见数据!
示例1:csv - 读取CSV文件
import csv
from pathlib import Path
# 创建测试CSV文件
csv_file = Path('test.csv')
content = '''姓名,年龄,城市
张三,25,北京
李四,30,上海
王五,28,广州'''
csv_file.write_text(content, encoding='utf-8')
# 读取CSV
with csv_file.open('r', encoding='utf-8') as f:
# 使用DictReader按字典读取
reader = csv.DictReader(f)
for row in reader:
print(f'{row["姓名"]}: {row["年龄"]}岁, {row["城市"]}')
# 使用reader按列表读取
print('\n按列表读取:')
with csv_file.open('r', encoding='utf-8') as f:
reader = csv.reader(f)
for i, row in enumerate(reader, 1):
print(f'第{i}行: {row}')示例2:csv - 写入CSV文件
import csv
from pathlib import Path
# 准备数据
data = [
['产品', '价格', '库存'],
['笔记本', 5999.99, 10],
['鼠标', 99.5, 50],
['键盘', 199.0, 30]
]
# 写入CSV
output_file = Path('products.csv')
with output_file.open('w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerows(data)
print('CSV文件已创建')
# 使用DictWriter
users = [
{'name': '张三', 'age': 25, 'city': '北京'},
{'name': '李四', 'age': 30, 'city': '上海'}
]
with Path('users.csv').open('w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=['name', 'age', 'city'])
writer.writeheader() # 写入标题行
writer.writerows(users)
print('用户CSV文件已创建')示例3:sqlite3 - 基本操作
import sqlite3
from pathlib import Path
# 删除旧的数据库
if Path('test.db').exists():
Path('test.db').unlink()
# 连接数据库
conn = sqlite3.connect('test.db')
cursor = conn.cursor()
# 创建表
cursor.execute('''
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER,
email TEXT
)
''')
# 插入数据
users_data = [
('张三', 25, 'zhangsan@example.com'),
('李四', 30, 'lisi@example.com'),
('王五', 28, 'wangwu@example.com')
]
cursor.executemany(
'INSERT INTO users (name, age, email) VALUES (?, ?, ?)',
users_data
)
conn.commit()
# 查询数据
cursor.execute('SELECT * FROM users')
print('所有用户:')
for row in cursor.fetchall():
print(f' ID: {row[0]}, 姓名: {row[1]}, 年龄: {row[2]}')
conn.close()示例4:sqlite3 - 高级查询
import sqlite3
conn = sqlite3.connect('test.db')
cursor = conn.cursor()
# 条件查询
cursor.execute('SELECT * FROM users WHERE age > 25')
print('年龄大于25的用户:')
for row in cursor.fetchall():
print(f' {row[1]}: {row[2]}岁')
# 使用参数化查询
age_limit = 27
cursor.execute(
'SELECT * FROM users WHERE age > ?',
(age_limit,)
)
print(f'\n年龄大于{age_limit}的用户:')
for row in cursor.fetchall():
print(f' {row[1]}: {row[2]}岁')
# 更新数据
cursor.execute('UPDATE users SET age = age + 1 WHERE name = ?', ('张三',))
conn.commit()
print('\n更新后的张三:')
cursor.execute('SELECT * FROM users WHERE name = ?', ('张三',))
print(f' {cursor.fetchone()}')
conn.close()想把Python对象保存到文件?
pickle模块帮你实现对象的序列化和反序列化。
示例1:序列化和反序列化
import pickle
# 准备数据
data = {
'name': '张三',
'age': 25,
'skills': ['Python', 'JavaScript'],
'scores': {'math': 90, 'english': 85}
}
# 序列化为字节
serialized = pickle.dumps(data)
print(f'序列化后: {serialized[:50]}...')
print(f'长度: {len(serialized)} 字节')
# 反序列化
deserialized = pickle.loads(serialized)
print(f'\n反序列化后: {deserialized}')
# 验证
print(f'是否相等: {data == deserialized}')示例2:读写pickle文件
import pickle
from pathlib import Path
# 准备复杂对象
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f'Person({self.name}, {self.age})'
people = [
Person('张三', 25),
Person('李四', 30),
Person('王五', 28)
]
# 写入pickle文件
with Path('people.pkl').open('wb') as f:
pickle.dump(people, f)
print('pickle文件已保存')
# 读取pickle文件
with Path('people.pkl').open('rb') as f:
loaded_people = pickle.load(f)
print(f'\n加载的对象:')
for person in loaded_people:
print(f' {person}')示例3:缓存计算结果
import pickle
from pathlib import Path
def expensive_computation(n):
"""模拟昂贵的计算"""
print(f'正在进行计算...')
result = sum(i ** 2 for i in range(n))
return result
cache_file = Path('computation_cache.pkl')
# 尝试从缓存加载
if cache_file.exists():
with cache_file.open('rb') as f:
result = pickle.load(f)
print(f'从缓存加载结果: {result}')
else:
# 执行计算并保存
result = expensive_computation(1000000)
with cache_file.open('wb') as f:
pickle.dump(result, f)
print(f'计算结果已缓存: {result}')需要随机数?random模块应有尽有。
示例1:基本随机数
import random
# 随机浮点数 [0.0, 1.0)
print(f'随机浮点数: {random.random()}')
# 指定范围的随机浮点数
print(f'1.0-10.0: {random.uniform(1.0, 10.0)}')
# 随机整数 [a, b]
print(f'1-100: {random.randint(1, 100)}')
# 随机整数 [a, b)
print(f'1-10: {random.randrange(1, 10)}')
# 步进式随机整数
print(f'偶数: {random.randrange(0, 10, 2)}')示例2:序列操作
import random
# 从列表中随机选择
items = ['苹果', '香蕉', '橘子', '葡萄']
print(f'随机选择: {random.choice(items)}')
# 随机选择多个(可重复)
print(f'随机选择2个: {random.choices(items, k=2)}')
# 随机选择多个(不重复)
print(f'不重复选择2个: {random.sample(items, 2)}')
# 打乱列表
numbers = list(range(10))
random.shuffle(numbers)
print(f'打乱后: {numbers}')示例3:随机种子和分布
import random
# 设置随机种子(保证可重现)
random.seed(42)
print(f'种子42: {random.randint(1, 100)}')
random.seed(42)
print(f'再次种子42: {random.randint(1, 100)}')
# 高斯分布(正态分布)
mean, std = 0, 1
print(f'高斯分布: {random.gauss(mean, std)}')
print(f'高斯分布: {random.gauss(mean, std)}')
# 指数分布
print(f'指数分布: {random.expovariate(1.0)}')示例4:生成随机密码
import random
import string
def generate_password(length=12):
"""生成随机密码"""
# 包含大小写字母、数字和特殊字符
characters = string.ascii_letters + string.digits + '!@#$%^&*'
password = ''.join(random.choices(characters, k=length))
return password
# 生成密码
for i in range(5):
print(f'密码{i+1}: {generate_password(12)}')
# 生成可读的密码(避免易混淆字符)
safe_chars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789'
safe_password = ''.join(random.choices(safe_chars, k=12))
print(f'安全密码: {safe_password}')需要生成唯一标识符?uuid模块帮你搞定。
示例1:基本UUID生成
import uuid
# uuid1 - 基于时间戳和MAC地址
u1 = uuid.uuid1()
print(f'UUID1: {u1}')
print(f'版本: {u1.version}')
print(f'十六进制: {u1.hex}')
# uuid4 - 随机生成(最常用)
u4 = uuid.uuid4()
print(f'\nUUID4: {u4}')
print(f'版本: {u4.version}')
# 比较UUID
u4_another = uuid.uuid4()
print(f'\n是否相等: {u4 == u4_another}')
print(f'是否不同: {u4 != u4_another}')示例2:UUID作为字典键
import uuid
# 使用UUID作为字典键
data = {}
for i in range(3):
key = uuid.uuid4()
data[key] = f'数据{i}'
print('字典内容:')
for key, value in data.items():
print(f' {key}: {value}')
# 查找
first_key = list(data.keys())[0]
print(f'\n查找 {first_key}: {data[first_key]}')示例3:UUID字符串转换
import uuid
# 生成UUID
u = uuid.uuid4()
# 转换为字符串
uuid_str = str(u)
print(f'字符串形式: {uuid_str}')
# 从字符串创建UUID
u_from_str = uuid.UUID(uuid_str)
print(f'从字符串恢复: {u_from_str}')
print(f'是否相等: {u == u_from_str}')
# 获取不同格式
print(f'\n十六进制: {u.hex}')
print(f'字节: {u.bytes}')
print(f'整数: {u.int}')
print(f'URN: {u.urn}')示例4:生成短ID
import uuid
import base62
def generate_short_id():
"""生成短ID"""
# 生成UUID
u = uuid.uuid4()
# 转换为整数
num = u.int
# 转换为base62(更短)
# 简化版:使用十六进制的前8位
return u.hex[:8]
# 生成短ID
for i in range(10):
short_id = generate_short_id()
print(f'短ID {i+1}: {short_id}')
# 注意:短ID有碰撞风险,仅适用于特定场景养成"先查标准库"的习惯,你会发现:
遇到问题时,试试这样搜索:
python standard library for [你的需求]
很可能一个完美的轮子已经在等你了!
Python的标准库就像一个装满工具的宝箱。
20个模块覆盖了开发中最常见的需求:日志、文件、命令行、数据、时间、并发、类型、文本处理和简单存储。
掌握了它们,你的代码会更加精简、专业和易于维护。
记住:不要重复造轮子,先看看Python已经给了你什么。
💬 你平时最常用哪个Python内置模块?
评论区聊聊你的经验~
本文分享自 Nicholas与Pypi 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!