知用网
霓虹主题四 · 更硬核的阅读氛围

标准库不是万能胶:这些使用注意事项很多人踩过坑

发布时间:2026-02-10 18:12:03 阅读:8 次

写 Python 时,import 一打就来,os、json、datetime、re…看着都熟,用着也顺。但真到线上出问题,比如时间差八小时、文件路径在 Windows 和 Linux 上表现不一、正则匹配突然漏掉数据——回头一看,八成是标准用法没对味。

别把 datetime 当本地时间用

新手常写 datetime.now() 就直接存数据库或传接口,结果服务器时区是 UTC,本地开发机是东八区,同一段代码,测试没问题,上线就错乱。更隐蔽的是 datetime.utcnow(),它返回的是 naive 时间对象(无时区信息),看似“UTC”,实则只是按 UTC 时钟算的本地时间,不带 tzinfo,后续做时区转换会静默失败。

from datetime import datetime

# ❌ 危险:naive 对象,时区模糊
now = datetime.utcnow()  # 不是 timezone-aware!

# ✅ 推荐:显式声明时区
from datetime import timezone
now_utc = datetime.now(timezone.utc)

os.path 拼路径?小心斜杠和盘符

Windows 用反斜杠 \,Linux/macOS 用正斜杠 /。有人硬写 'data/' + filename,本地跑得好好的,一上 Linux 测试环境就报 FileNotFoundError;还有人用 os.path.join('C:', 'folder', 'file.txt'),在 Windows 上可能变成 C:folder\file.txt(缺了分隔符),因为 os.path.join 遇到盘符会重置路径逻辑。

更稳妥的做法是统一用 pathlib.Path ——Python 3.4+ 的标准库成员,跨平台、可读性强、支持链式操作:

from pathlib import Path

# ✅ 清晰、安全、跨平台
config_path = Path("conf") / "app.yaml"
log_dir = Path("/var/log/myapp")
log_dir.mkdir(parents=True, exist_ok=True)

json.dumps 处理中文,默认 encode 成乱码?

本地调试时 print(json.dumps(data)) 看着好好的,一写入文件或发 HTTP 请求,中文全变 \u4f60\u597d。这不是 bug,是默认行为:json.dumpsensure_ascii=True 会强制转义非 ASCII 字符。

多数场景下,你其实想要原生中文输出:

import json

data = {"姓名": "张三", "城市": "杭州"}

# ❌ 默认输出 Unicode 转义
print(json.dumps(data))  # {"\u59d3\u540d": "\u5f20\u4e09", ...}

# ✅ 加上 ensure_ascii=False
print(json.dumps(data, ensure_ascii=False))  # {"姓名": "张三", "城市": "杭州"}

re.match 和 re.search 别混用

一个常见误解:以为 re.match 是“找匹配”,其实它是“从开头匹配”。比如验证手机号,写 re.match(r'1[3-9]\d{9}', text),如果用户输入的是 我的号码是13812345678,匹配直接失败——因为 match 要求模式必须从字符串首字符开始生效。

真正做“是否包含”判断,该用 re.search;要做严格开头校验(如路由匹配、协议头识别),才用 match

shutil.copy 和 shutil.copy2 的差别不止是多两个字

shutil.copy 只复制内容和权限位,不保留修改时间、访问时间等元数据;shutil.copy2 才会尽力复制所有可用的文件元信息。如果你在做备份脚本或部署工具,忽略这点,可能导致缓存失效、构建跳过、甚至 CI 流水线误判文件未变更。

另外,shutil.copytree 默认不覆盖已有目录,遇到目标存在就报错。需要覆盖时,得手动加 dirs_exist_ok=True(Python 3.8+),否则还得先 rmtree 再 copy,容易误删。