目录
1.3 pathlib模块:面向对象的路径操作(Python3.4+)
Python的强大之处很大程度上来自于其丰富的标准库模块。本文将深入探讨Python中最常用的几个模块:os
、sys
、pathlib
用于系统操作,datetime
用于时间处理,以及json
、pickle
用于数据序列化。掌握这些模块能极大提升你的Python开发效率。
一、系统操作三剑客:os、sys、pathlib
1.1 os模块:操作系统交互的瑞士军刀
os
模块提供了丰富的方法来与操作系统进行交互,特别是文件系统和进程管理。
常用功能示例:
import os
# 获取当前工作目录
current_dir = os.getcwd()
print(f"当前目录: {current_dir}")
# 改变工作目录
os.chdir('../')
# 列出目录内容
print("目录内容:", os.listdir('.'))
# 创建/删除目录
os.makedirs('test_dir/sub_dir', exist_ok=True)
os.rmdir('test_dir/sub_dir')
# 路径拼接
file_path = os.path.join('data', 'files', 'test.txt')
print(f"拼接后的路径: {file_path}")
# 路径分割
dirname, filename = os.path.split(file_path)
print(f"目录部分: {dirname}, 文件名部分: {filename}")
# 检查路径存在
print("文件存在?", os.path.exists(file_path))
# 获取文件大小(字节)
if os.path.exists(file_path):
print(f"文件大小: {os.path.getsize(file_path)} bytes")
# 执行系统命令
os.system('ls -l') # Linux/macOS
# os.system('dir') # Windows
os.path子模块特别说明:
os.path
是os
模块中最常用的子模块,提供了一系列路径相关的实用函数:
import os.path
path = "/home/user/data/file.txt"
print(os.path.basename(path)) # file.txt
print(os.path.dirname(path)) # /home/user/data
print(os.path.splitext(path)) # ('/home/user/data/file', '.txt')
print(os.path.isabs(path)) # True
print(os.path.isdir(path)) # False
print(os.path.isfile(path)) # 取决于文件是否存在
1.2 sys模块:系统相关参数和函数
sys
模块提供了与Python解释器交互的变量和函数。
核心功能展示:
import sys
# Python解释器版本信息
print("Python版本:", sys.version)
print("版本信息:", sys.version_info)
# 命令行参数
print("脚本名称:", sys.argv[0])
print("参数列表:", sys.argv[1:])
# 模块搜索路径
print("模块搜索路径:")
for path in sys.path:
print(f" {path}")
# 标准输入/输出/错误
sys.stdout.write("这是标准输出\n")
sys.stderr.write("这是标准错误输出\n")
# 退出程序
if len(sys.argv) < 2:
sys.exit("错误: 需要提供参数!")
# 递归限制
print("默认递归深度限制:", sys.getrecursionlimit())
sys.setrecursionlimit(2000)
# 引用计数
a = [1, 2, 3]
print("a的引用计数:", sys.getrefcount(a) - 1) # getrefcount会临时增加1
实用技巧:重定向输出
import sys
# 将标准输出重定向到文件
original_stdout = sys.stdout
with open('output.log', 'w') as f:
sys.stdout = f
print("这条消息会写入文件")
sys.stdout = original_stdout
print("这条消息会显示在控制台")
1.3 pathlib模块:面向对象的路径操作(Python3.4+)
pathlib
提供了面向对象的路径操作方式,比传统的os.path
更加直观和方便。
基本用法:
from pathlib import Path
# 创建Path对象
p = Path('/home/user/data/file.txt')
# 常用属性和方法
print("父目录:", p.parent)
print("文件名:", p.name)
print("后缀名:", p.suffix)
print("不带后缀的文件名:", p.stem)
print("绝对路径:", p.absolute())
# 路径拼接
new_p = p.parent / 'new_dir' / 'new_file.csv'
print("新路径:", new_p)
# 文件操作
if not p.exists():
p.touch() # 创建空文件
# 目录操作
dir_p = Path('test_dir/sub_dir')
dir_p.mkdir(parents=True, exist_ok=True) # 创建目录,包括父目录
# 遍历目录
for file in Path('.').glob('*.py'): # 当前目录所有.py文件
print(file.name)
# 读写文件
p.write_text("Hello, Pathlib!") # 写入文本
content = p.read_text() # 读取文本
print("文件内容:", content)
pathlib与os.path的对比
操作 | os.path方式 | pathlib方式 |
---|---|---|
路径拼接 | os.path.join(a, b, c) |
Path(a)/b/c |
获取父目录 | os.path.dirname(p) |
p.parent |
获取文件名 | os.path.basename(p) |
p.name |
获取后缀 | os.path.splitext(p)[1] |
p.suffix |
检查存在 | os.path.exists(p) |
p.exists() |
是否是文件 | os.path.isfile(p) |
p.is_file() |
是否是目录 | os.path.isdir(p) |
p.is_dir() |
建议:新项目优先使用pathlib
,代码更简洁直观,且面向对象的设计更符合Python风格。
二、时间处理:datetime模块
datetime
模块提供了日期和时间处理的类,是Python时间操作的核心模块。
2.1 主要类介绍
datetime.date
:处理日期(年、月、日)datetime.time
:处理时间(时、分、秒、微秒)datetime.datetime
:处理日期和时间datetime.timedelta
:处理时间间隔datetime.tzinfo
:时区信息基类
2.2 基本使用示例
from datetime import datetime, date, time, timedelta
# 获取当前日期和时间
now = datetime.now()
print("当前时间:", now)
# 获取当前日期
today = date.today()
print("今天日期:", today)
# 创建特定日期/时间
some_date = date(2023, 7, 15)
some_time = time(14, 30, 15)
some_datetime = datetime(2023, 7, 15, 14, 30, 15)
print("特定日期:", some_date)
print("特定时间:", some_time)
print("特定日期时间:", some_datetime)
# 访问属性
print("年:", some_datetime.year)
print("月:", some_datetime.month)
print("日:", some_datetime.day)
print("时:", some_datetime.hour)
print("分:", some_datetime.minute)
print("秒:", some_datetime.second)
2.3 时间计算与格式化
# 时间计算
one_day = timedelta(days=1)
tomorrow = today + one_day
yesterday = today - one_day
print("明天:", tomorrow)
print("昨天:", yesterday)
# 时间差计算
start_time = datetime(2023, 1, 1)
end_time = datetime(2023, 7, 15)
duration = end_time - start_time
print("时间差:", duration)
print("天数:", duration.days)
print("秒数:", duration.total_seconds())
# 格式化输出
formatted = now.strftime("%Y-%m-%d %H:%M:%S")
print("格式化时间:", formatted)
# 字符串解析
parsed_time = datetime.strptime("2023-07-15 14:30:00", "%Y-%m-%d %H:%M:%S")
print("解析后的时间:", parsed_time)
2.4 时区处理(Python3.9+)
from zoneinfo import ZoneInfo # Python 3.9+
# 创建带时区的时间
utc_time = datetime.now(ZoneInfo("UTC"))
print("UTC时间:", utc_time)
beijing_time = datetime.now(ZoneInfo("Asia/Shanghai"))
print("北京时间:", beijing_time)
# 时区转换
ny_time = beijing_time.astimezone(ZoneInfo("America/New_York"))
print("纽约时间:", ny_time)
三、数据序列化:json与pickle
3.1 json模块:跨语言的数据交换
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,也易于机器解析和生成。
基本用法:
import json
# Python对象
data = {
"name": "张三",
"age": 30,
"married": True,
"children": ["小明", "小红"],
"address": {
"street": "人民路",
"city": "北京"
}
}
# 序列化为JSON字符串
json_str = json.dumps(data, ensure_ascii=False, indent=2)
print("JSON字符串:")
print(json_str)
# 写入JSON文件
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
# 从JSON字符串反序列化
loaded_data = json.loads(json_str)
print("从JSON字符串加载:")
print(loaded_data)
# 从JSON文件读取
with open('data.json', 'r', encoding='utf-8') as f:
file_data = json.load(f)
print("从JSON文件加载:")
print(file_data)
高级特性:
# 自定义对象序列化
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def person_to_dict(obj):
if isinstance(obj, Person):
return {'name': obj.name, 'age': obj.age}
raise TypeError(f"Object of type {obj.__class__.__name__} is not JSON serializable")
p = Person("李四", 25)
person_json = json.dumps(p, default=person_to_dict, ensure_ascii=False)
print("自定义对象序列化:", person_json)
# 使用JSONEncoder
class PersonEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Person):
return {'name': obj.name, 'age': obj.age}
return super().default(obj)
person_json = json.dumps(p, cls=PersonEncoder, ensure_ascii=False)
print("使用JSONEncoder:", person_json)
3.2 pickle模块:Python对象序列化
pickle
模块实现了对Python对象结构的二进制序列化和反序列化,是Python特有的数据格式。
基本使用:
import pickle
# Python对象
data = {
'a': [1, 2.0, 3+4j],
'b': ("字符串", b"字节串"),
'c': {None, True, False}
}
# 序列化为字节串
pickled_data = pickle.dumps(data)
print("Pickle数据:", pickled_data)
# 写入文件
with open('data.pkl', 'wb') as f:
pickle.dump(data, f)
# 从字节串反序列化
unpickled_data = pickle.loads(pickled_data)
print("反序列化数据:", unpickled_data)
# 从文件读取
with open('data.pkl', 'rb') as f:
file_data = pickle.load(f)
print("从文件加载:", file_data)
自定义对象序列化:
class MyClass:
def __init__(self, value):
self.value = value
self.computed = value * 2
def __reduce__(self):
return (self.__class__, (self.value,))
obj = MyClass(10)
# 序列化
pickled_obj = pickle.dumps(obj)
# 反序列化
new_obj = pickle.loads(pickled_obj)
print("反序列化对象:", new_obj.value, new_obj.computed) # 输出: 10 20
3.3 json与pickle对比
特性 | json | pickle |
---|---|---|
数据格式 | 文本 | 二进制 |
跨语言支持 | 是 | 否 (仅Python) |
安全性 | 高 | 低 (可能执行任意代码) |
速度 | 较慢 | 较快 |
支持Python类型 | 基本类型(dict,list,str等) | 几乎所有Python类型 |
文件扩展名 | .json | .pkl, .pickle |
适用场景 | 数据交换,配置文件 | Python内部数据持久化 |
安全警告:不要反序列化不受信任来源的pickle数据,这可能导致代码执行!
四、实用技巧与最佳实践
4.1 模块联合使用示例
from pathlib import Path
import datetime
import json
# 创建带时间戳的日志文件
log_dir = Path('logs')
log_dir.mkdir(exist_ok=True)
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
log_file = log_dir / f"app_{timestamp}.log"
# 准备日志数据
log_data = {
'timestamp': str(datetime.datetime.now()),
'level': 'INFO',
'message': 'Application started',
'status': 'OK'
}
# 写入JSON日志
with log_file.open('w', encoding='utf-8') as f:
json.dump(log_data, f, indent=2, ensure_ascii=False)
print(f"日志已写入: {log_file}")
4.2 异常处理与模块使用
from pathlib import Path
import json
def load_config(config_path):
path = Path(config_path)
try:
with path.open('r', encoding='utf-8') as f:
return json.load(f)
except FileNotFoundError:
print(f"错误: 配置文件 {path} 不存在")
except json.JSONDecodeError as e:
print(f"错误: 配置文件 {path} 不是有效的JSON格式")
print(f"详细错误: {e}")
except Exception as e:
print(f"未知错误: {e}")
return None
config = load_config('config.json')
if config:
print("配置加载成功:", config)
4.3 性能考虑
路径操作:对于大量路径操作,
pathlib
可能比os.path
稍慢,但可读性更好JSON处理:对于大型JSON文件,考虑使用
ijson
等流式解析库时间操作:频繁的时间操作中,
datetime
对象的创建可能成为瓶颈,考虑缓存或使用简单数据结构
小贴士:ijson 是一个高效的流式 JSON 解析器,适用于处理大型或无限数据集。它通过迭代器逐个读取数据,而不是一次性加载整个文件到内存中,从而节省大量内存。
# pip install ijson
import ijson
with open('data.json', 'r') as f:
# 使用前缀方法逐个读取对象或数组中的元素
for item in ijson.items(f, 'item'):
process(item)
结语
Python的标准库提供了丰富而强大的模块,能够处理各种常见编程任务。通过掌握os
/sys
/pathlib
进行系统操作,使用datetime
处理时间日期,以及利用json
/pickle
进行数据序列化,你可以显著提高开发效率并编写更健壮的代码。
记住:
新项目优先使用
pathlib
替代os.path
时间处理注意时区问题
数据交换优先使用JSON,Python内部持久化考虑pickle
始终处理可能的异常情况
希望本文能帮助你更好地理解和使用这些Python常用模块。实践是最好的学习方式,尝试在自己的项目中使用这些模块,你会发现它们的强大之处!