欢迎来到 第五阶段:工程化与底层(专家篇)。
写出代码能跑是新手(Junior)的标准;写出优雅、可维护、不仅能跑还能跑得稳的代码,是资深工程师(Senior)的标准。
对于你(Node.js 背景),这一章相当于从“写 JS 脚本”进阶到“构建 TypeScript 大型架构”。
1. 面向对象编程 (OOP):架构的基石
Python 是多范式语言(既能写脚本,也能写类)。很多从 Java 转过来的人喜欢万物皆类,从 JS 转过来的人喜欢万物皆函数。
什么时候该用类 (class),什么时候用函数 (def)?
黄金法则:
如果你只需要行为(输入 -> 处理 -> 输出),用 函数。
如果你需要同时管理状态(Data)和行为(Methods),用 类。
场景 A:发送邮件 (适合函数)
不需要记住之前的状态,发完就走。
Python
def send_email(to: str, content: str):
# 连接 SMTP... 发送... 关闭
pass场景 B:AI 对话客户端 (适合类)
需要记住 api_key,需要记住 history (聊天记录上下文)。
Python
class AIChatBot:
def __init__(self, api_key: str, model: str = "deepseek-chat"):
"""构造函数:初始化状态"""
self.client = OpenAI(api_key=api_key) # 状态 1: 连接客户端
self.model = model # 状态 2: 模型配置
self.history = [] # 状态 3: 记忆
def chat(self, user_input: str) -> str:
"""方法:使用状态并更新状态"""
self.history.append({"role": "user", "content": user_input})
response = self.client.chat.completions.create(
model=self.model,
messages=self.history
)
reply = response.choices[0].message.content
self.history.append({"role": "assistant", "content": reply})
return reply
# 使用
bot = AIChatBot("sk-...")
print(bot.chat("你好")) # 它记得之前的配置
print(bot.chat("我刚才说什么了?")) # 它记得之前的历史2. 高级特性:Python 的“黑魔法”
掌握这三个特性,你的代码会瞬间变得“Pythonic”(地道)。
A. 装饰器 (@decorator)
本质:高阶函数(Higher-Order Function)。在不修改原函数代码的情况下,给函数增加额外的功能(如日志、计时、鉴权、重试)。
Node.js 类比:类似于 Express 的 Middleware,或者 AOP (面向切面编程)。
实战:写一个“自动重试”装饰器 (AI 调用必备)
Python
import time
from functools import wraps
def retry(max_retries=3, delay=1):
def decorator(func):
@wraps(func) # 保持原函数的元数据 (name, docstring)
def wrapper(*args, **kwargs):
for i in range(max_retries):
try:
return func(*args, **kwargs) # 尝试执行原函数
except Exception as e:
print(f"❌ 第 {i+1} 次尝试失败: {e},{delay}秒后重试...")
time.sleep(delay)
raise Exception("🔥 重试多次失败")
return wrapper
return decorator
# 使用装饰器:这就把重试逻辑注入到了 call_ai_api 中
@retry(max_retries=3, delay=2)
def call_ai_api():
import random
if random.random() < 0.7: # 模拟 70% 概率失败
raise ValueError("网络波动")
return "✅ 成功获取数据"
# 调用
print(call_ai_api())B. 生成器 (yield)
本质:惰性求值 (Lazy Evaluation)。函数执行到 yield 会暂停并返回一个值,下次调用 next() 从暂停处继续。
优势:极度省内存。
实战:读取 10GB 的日志文件
如果用 f.readlines(),内存直接爆炸。用 yield,内存占用几乎为零。
Python
def read_large_file(file_path):
with open(file_path, 'r') as f:
for line in f:
yield line.strip() # 每次只吐出一行,不把整个文件加载到内存
# 使用
log_gen = read_large_file("huge_log.txt")
for line in log_gen:
if "ERROR" in line:
print(f"找到错误: {line}")C. 上下文管理器 (with)
本质:自动管理资源(打开/关闭)。
原理:实现了 __enter__ 和 __exit__ 方法。
实战:自定义一个计时器
Python
import time
class Timer:
def __enter__(self):
self.start = time.time()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.end = time.time()
print(f"⏱️ 耗时: {self.end - self.start:.2f} 秒")
# 使用
with Timer():
# 这里放任何你想计时的代码
time.sleep(1.5)
print("任务完成")
# 退出缩进时,自动打印耗时3. 代码质量:像专家一样写代码
A. 类型注解 (Type Hints)
Python 3.5+ 引入。虽然 Python 运行时不强制类型,但在大型项目中,它是文档,也是救命稻草。
Python
from typing import List, Dict, Optional
# 不好的写法
def process_data(data):
return data['items']
# 好的写法 (IDE 会有智能提示,配合 mypy 工具可以静态检查)
def process_data(data: Dict[str, List[int]]) -> List[int]:
"""
处理数据
:param data: 包含 'items' 键的字典,值为整数列表
"""
return data.get('items', [])B. 单元测试 (pytest)
丢掉 Python 自带的 unittest 吧,pytest 才是业界标准。它不需要写类,直接写 assert。
实战:测试上面的重试函数
安装:
pip install pytest新建
test_app.py:
Python
import pytest
from your_module import AIChatBot # 假设你把代码存成了文件
def test_chatbot_initialization():
bot = AIChatBot(api_key="sk-test")
assert bot.model == "deepseek-chat"
assert len(bot.history) == 0
def test_chat_flow():
# 这里通常会 Mock 掉 OpenAI 的调用,防止真的扣费
# 但为了演示简单,我们只测逻辑
pass- 运行:在终端输入
pytest。
4. 部署进阶:Docker 生产级最佳实践
在第四阶段我们讲了基础 Docker。这里讲优化。
目标:减小镜像体积,加快构建速度。
使用多阶段构建 (Multi-stage Build):
Node.js 开发者很熟悉这个,Python 也一样。我们不需要把编译工具(gcc)带到生产环境。
Dockerfile.prod (生产级配置)
Dockerfile
# 第一阶段:构建依赖 (Builder)
FROM python:3.10-slim as builder
WORKDIR /app
COPY requirements.txt .
# --user 安装到用户目录,方便后续复制
# --no-warn-script-location 忽略路径警告
RUN pip install --user --no-cache-dir -r requirements.txt
# 第二阶段:运行环境 (Runner) - 纯净的镜像
FROM python:3.10-slim
WORKDIR /app
# 从 builder 阶段只复制安装好的库,不复制 pip 等工具
COPY --from=builder /root/.local /root/.local
COPY . .
# 确保 Python 能找到刚刚复制的库
ENV PATH=/root/.local/bin:$PATH
# 生产环境通常用 gunicorn 或 uvicorn 启动
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]第五阶段实战作业:重构 AI 内容工厂
你现在的 main.py 可能所有的逻辑都写在一起。请按照工程化标准重构它:
OOP 重构:创建一个
ContentGenerator类,把generate_article和generate_image方法封装进去。增加装饰器:给所有 AI 调用的方法加上
@retry和@log_execution_time(记录耗时)。类型注解:给所有函数参数加上 Type Hints。
编写测试:写一个
test_generator.py,测试 Prompt 拼接逻辑是否正确。
完成了这一步,你写的就不再是“脚本”,而是**“企业级软件”**了。
需要我帮你演示如何把之前的代码重构成这个 OOP 版本吗?