Python · 02 核心能力
真正不同的地方:动态类型代价、GIL、asyncio、性能与适合边界。
1. 动态类型:效率与风险
| 好处 | 改得快、脚本多、原型一天能出 |
| 风险 | 重构胆怯、线上类型相关 Bug 更隐蔽、IDE/审查更难 |
我的做法:
- 对外:FastAPI + Pydantic(入参出参强制结构)
- 对内脚本:短小;重要路径加注解
- 与 Java 交接:字段名、枚举值、错误码写成书面契约
2. GIL 与并发现实
CPython 有 GIL:多线程对 CPU 密集帮助有限。
| 场景 | 选择 | 原因 |
|---|---|---|
| 等 HTTP / 等模型 | asyncio 或线程 | 多数时间在等 IO |
| CPU 密集(大文件本地重算等) | 多进程、或丢给别的服务 | 绕过 GIL |
| 真要吞吐 | 多实例水平扩 | 先扩架构 |
和 Java 比:Java 真多线程共享内存更常见;Python 更适合 旁路 IO 服务,不适合硬扛所有核心域逻辑。
3. asyncio 怎么用才不踩坑
适合: 同时等多个模型 API、扇出 HTTP、websocket。
不适合: 在 async 函数里调用阻塞的 requests / 重 CPU 而不加 to_thread。
原则:
- 要么整条链 async(
httpx.AsyncClient),要么诚实用同步 + 线程池 - 不要「半吊子 async」:看起来并发,实际全堵在同步调用上
- 取消与超时:
asyncio.wait_for/ 客户端 timeout,避免任务挂死
4. 性能边界
- 默认解释执行,绝对性能通常弱于 Java/Go
- 真瓶颈常在: 模型延迟、网络、错误重试、速率限制——不在
for写得不够炫 - 需要吞吐:水平扩多实例,或把热点迁到 Java/Go/专用推理服务
- 大文件:流式处理,别一次性
read()进内存
判断: 性能不够先看架构与下游,再怨语言。
5. 适合什么 / 不适合什么
| 适合 | 不适合 |
|---|---|
| AI API 封装、批处理、运维脚本 | 超大单体复杂中台的第一选择 |
| 快速内部工具、数据清洗 | 强规范、强类型的超大协作域(可仍用 Java) |
| 给 Java 调用的专项服务 | 已有稳定 Java 域还强行重写 |
| Prompt / 流程验证 | 强事务库存核心(除非只做读写旁路) |
我为什么用 Python 做 AI / 自动化
- 模型与工具 SDK 往往 Python 最全、示例最多
- 能快速验证 Prompt / 流程,再决定是否迁回 Java
- 分工清晰:Java 管业务与状态,Python 管模型与脚本
下一篇:03 框架与生态