第6章 6.5 综合实战:跨端电商 App
⏱️ 学习时长:90 分钟 | 🎯 难度:进阶 | 📖 第 30/45 章
🎯 开场 3 分钟:为什么要学这个?
上一章我们折腾了 nvue 原生渲染,搞定了「条件编译」这个香饽饽——一套代码,多端生效,爽不爽?
但光会页面布局还不够,真正的电商 App 离不开数据流转。你有没有想过:
- 商品列表从哪来?订单怎么生成?
- 用户下单后,库存怎么扣减?
- 那些「限时秒杀」「拼团活动」背后是什么逻辑?
这一章,我们用 Python 写一个电商数据处理工具,模拟电商 App 的核心业务流程。说是 Python,其实是给下一章的 TypeScript 改造打前站——你先在 Python 里把业务逻辑搞明白,换成 TypeScript 就是换件衣服的事。
学完这章,你就能:
- ✅ 用 Python 处理商品、订单、用户数据
- ✅ 理解电商核心模块的数据流
- ✅ 为下一章 TypeScript 改造做好准备
🧱 基础 25 分钟:核心概念
什么\n\n
\n\n
\n\n是电商数据模型?
💡 生活类比:电商数据模型就像餐厅的菜单 + 订单本
- 商品 = 菜单上的菜
- 购物车 = 你点菜的清单
- 订单 = 服务员记下的正式订单
电商 App 本质是数据流转:
用户浏览商品 → 加入购物车 → 下单 → 支付 → 商家发货 → 收货确认
每一步都在操作数据。我们用 Python 定义几个核心数据类:
# 定义商品模型
class Product:
def __init__(self, product_id, name, price, stock):
self.product_id = product_id # 商品ID
self.name = name # 商品名称
self.price = price # 价格(元)
self.stock = stock # 库存(件)
# 定义购物车项
class CartItem:
def __init__(self, product, quantity):
self.product = product # 商品对象
self.quantity = quantity # 购买数量
# 定义订单模型
class Order:
def __init__(self, order_id, items):
self.order_id = order_id # 订单号
self.items = items # 购物车项列表
self.status = "pending" # 订单状态:pending/paid/shipped/completed
为什么要用类来组织数据?
💡 痛点:不用类的话,数据散落各处,改一处要改十处
用了类之后,数据 + 行为打包在一起,逻辑清晰
实战:创建商品和购物车
# 初始化几个商品
products = [
Product("P001", "iPhone 15", 5999, 100),
Product("P002", "AirPods Pro", 1999, 200),
Product("P003", "MacBook Air", 8999, 50),
]
# 创建购物车
cart = []
# 添加商品到购物车(模拟用户点击"加入购物车")
def add_to_cart(product_id, quantity):
for p in products:
if p.product_id == product_id:
cart.append(CartItem(p, quantity))
print(f"✅ 已添加 {p.name} x{quantity} 到购物车")
return
print("❌ 商品不存在")
# 测试加入购物车
add_to_cart("P001", 1)
add_to_cart("P002", 2)
预期输出:
✅ 已添加 iPhone 15 x1 到购物车
✅ 已添加 AirPods Pro x2 到购物车
什么是订单总价计算?
💡 生活类比:结账 = 把你点的东西加起来,乘以单价,再算折扣
订单总价怎么算?遍历购物车,每项 商品价格 × 数量,加起来:
# 计算购物车总价
def calculate_total(cart_items):
total = 0
for item in cart_items:
total += item.product.price * item.quantity
return total
# 试算一下
total = calculate_total(cart)
print(f"购物车总计:{total} 元")
预期输出:
购物车总计:9997 元
什么是库存扣减?
💡 痛点:超卖!两个人同时买最后一件,都显示成功,结果发不出货
解决:下单前检查库存,扣减时加锁(或用事务)
# 下单并扣减库存
def create_order(cart_items):
# 1. 先检查库存够不够
for item in cart_items:
if item.product.stock < item.quantity:
print(f"❌ 库存不足:{item.product.name} 库存{item.product.stock},需要{item.quantity}")
return None
# 2. 库存够,生成订单
order_id = "ORD" + "20240115" + "001"
order = Order(order_id, cart_items)
# 3. 扣减库存
for item in cart_items:
item.product.stock -= item.quantity
# 4. 清空购物车
cart_items.clear()
order.status = "paid"
print(f"✅ 订单创建成功!订单号:{order_id}")
return order
# 执行下单
order = create_order(cart)
if order:
print(f"订单状态:{order.status}")
预期输出:
✅ 订单创建成功!订单号:ORD20240115001
订单状态:paid
🔥 实战 35 分钟:3 个递进小项目
项目 1(5 分钟):购物车小工具
跟着抄就能跑,体验完整的「加购物车 → 查看 → 清空」流程:
# 项目1:购物车管理工具
class ShoppingCart:
def __init__(self):
self.items = []
def add(self, product, quantity):
self.items.append(CartItem(product, quantity))
print(f"🛒 {product.name} x{quantity} 已加入")
def view(self):
if not self.items:
print("购物车是空的")
return
print("\n===== 购物车 =====")
for item in self.items:
print(f"{item.product.name} x{item.quantity} = {item.product.price * item.quantity}元")
print(f"总计:{calculate_total(self.items)}元")
def clear(self):
self.items.clear()
print("🗑️ 购物车已清空")
# 使用
cart = ShoppingCart()
cart.add(Product("P001", "iPhone 15", 5999, 100), 1)
cart.add(Product("P002", "AirPods Pro", 1999, 200), 1)
cart.view()
预期输出:
🛒 iPhone 15 x1 已加入
🛒 AirPods Pro x1 已加入
===== 购物车 =====
iPhone 15 x1 = 5999元
AirPods Pro x1 = 1999元
总计:7998元
项目 2(15 分钟):从 JSON 文件读取商品数据
真实项目不会写死数据,一般从文件或 API 读取。新建 products.json:
[
{"product_id": "P001", "name": "iPhone 15", "price": 5999, "stock": 100},
{"product_id": "P002", "name": "AirPods Pro", "price": 1999, "stock": 200},
{"product_id": "P003", "name": "MacBook Air", "price": 8999, "stock": 50},
{"product_id": "P004", "name": "iPad Air", "price": 4799, "stock": 150},
{"product_id": "P005", "name": "Apple Watch", "price": 2999, "stock": 300}
]
然后用 Python 读取:
import json
# 从JSON文件加载商品数据
def load_products_from_json(filename):
with open(filename, 'r', encoding='utf-8') as f:
data = json.load(f)
return [Product(p['product_id'], p['name'], p['price'], p['stock']) for p in data]
# 使用
products = load_products_from_json('products.json')
# 显示所有商品
print("===== 商品列表 =====")
for p in products:
print(f"{p.product_id}: {p.name} - {p.price}元 (库存:{p.stock})")
# 查找商品
def find_product(products, product_id):
for p in products:
if p.product_id == product_id:
return p
return None
# 搜索
result = find_product(products, "P003")
if result:
print(f"\n🔍 找到:{result.name},价格{result.price}元")
预期输出:
===== 商品列表 =====
P001: iPhone 15 - 5999元 (库存:100)
P002: AirPods Pro - 1999元 (库存:200)
P003: MacBook Air - 8999元 (库存:50)
P004: iPad Air - 4799元 (库存:150)
P005: Apple Watch - 2999元 (库存:300)
🔍 找到:MacBook Air,价格8999元
项目 3(15 分钟):限时秒杀模拟器
组合前两个项目,做一个有点真实用的小工具——限时秒杀系统:
import json
import time
class FlashSale:
def __init__(self, products):
self.products = {p.product_id: p for p in products}
self.orders = []
def is_stock_available(self, product_id, quantity):
p = self.products.get(product_id)
if not p:
return False, "商品不存在"
if p.stock < quantity:
return False, f"库存不足,仅剩{p.stock}件"
return True, "可以购买"
def flash_buy(self, product_id, quantity, user_id):
# 检查库存
available, msg = self.is_stock_available(product_id, quantity)
if not available:
return {"success": False, "message": msg}
# 扣减库存
self.products[product_id].stock -= quantity
# 生成订单
order = {
"order_id": f"FS{int(time.time())}",
"user_id": user_id,
"product_id": product_id,
"quantity": quantity,
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S")
}
self.orders.append(order)
return {
"success": True,
"message": "秒杀成功!",
"order": order
}
# 模拟秒杀
flash = FlashSale(products)
# 模拟10个人同时抢P003(库存只有50)
print("===== 限时秒杀开始 =====")
results = []
for i in range(1, 11):
result = flash.flash_buy("P003", 1, f"USER{i}")
results.append(result)
if result["success"]:
print(f"USER{i} ✅ {result['message']} 订单号:{result['order']['order_id']}")
else:
print(f"USER{i} ❌ {result['message']}")
# 秒杀结束,检查库存
print(f"\n===== 秒杀结束 =====")
print(f"P003 剩余库存:{flash.products['P003'].stock}")
print(f"成功订单数:{len([o for o in flash.orders if o['product_id'] == 'P003'])}")
预期输出:
===== 限时秒杀开始 =====
USER1 ✅ 秒杀成功! 订单号:FS1705312800
USER2 ✅ 秒杀成功! 订单号:FS1705312801
...(继续)
USER10 ✅ 秒杀成功! 订单号:FS1705312809
===== 秒杀结束 =====
P003 剩余库存:40
成功订单数:10
💪 进阶 20 分钟:常见坑 + 性能小贴士
坑 1:可变默认参数
# ❌ 错误示例:默认参数用了列表,后面会出事
def add_items(product_id, cart=[]):
cart.append(product_id)
return cart
# ✅ 正确写法:默认参数用 None
def add_items_fixed(product_id, cart=None):
if cart is None:
cart = []
cart.append(product_id)
return cart
坑 2:循环修改列表
# ❌ 错误示例:边遍历边删除,会漏掉元素
cart = [1, 2, 3, 4, 5]
for item in cart:
if item < 3:
cart.remove(item)
# ✅ 正确写法:用切片或过滤
cart = [item for item in cart if item >= 3]
坑 3:浮点数价格计算
# ❌ 错误示例:浮点数精度问题
total = 0.1 + 0.2
print(total) # 0.30000000000000004
# ✅ 正确做法:用整数(分)或 Decimal
price_in_cent = 10 + 20 # 用分
print(price_in_cent / 100) # 0.30
坑 4:字典键不存在
# ❌ 错误示例:键不存在会抛异常
data = {"name": "iPhone"}
print(data["price"]) # KeyError
# ✅ 正确做法:用 get 或默认值
print(data.get("price", 0)) # 0
性能小贴士:批量操作减少循环
# ❌ 低效:循环里查字典
for item in cart:
product = None
for p in products:
if p.product_id == item.product_id:
product = p
break
# ✅ 高效:预先建字典
product_dict = {p.product_id: p for p in products}
for item in cart:
product = product_dict.get(item.product_id) # O(1) 查找
调试技巧:用 pdb 打打断点
import pdb
def calculate_total(cart_items):
pdb.set_trace() # 程序会在这里暂停,进入交互式调试
total = 0
for item in cart_items:
total += item.product.price * item.quantity
return total
运行时看到 (Pdb) 提示,输入 n 单步执行,p 变量名 查看变量值,c 继续运行。
✏️ 练习题 + 作业题
练习题(5 道,10 分钟内完成)
练习 1(2 分钟):改价格
- 输入:把 products.json 里 iPhone 15 改成 5499 元
- 预期输出:重新加载后显示新价格
- 提示:json.load() 后修改,再重新保存
练习 2(2 分钟):加个判断
- 输入:在 calculate_total 里加个判断,如果购物车为空返回 0
- 预期输出:空购物车调用返回 0,不报错
- 提示:if not cart_items: return 0
练习 3(3 分钟):处理新数据
- 输入:用项目 2 的方式加载这个 JSON:{"product_id": "P006", "name": "Vision Pro", "price": 29999, "stock": 20}
- 预期输出:打印出商品信息
- 提示:单个对象不用 json.load() 的列表推导式
练习 4(5 分钟):串接项目
- 输入:把项目 2 的商品加载 + 项目 3 的秒杀逻辑串起来
- 预期输出:能用 JSON 里的商品做秒杀
- 提示:把项目 2 的 products 传进 FlashSale
练习 5(3 分钟):找出 bug
- 输入:下面代码运行会报错,找出原因
data = [{"id": 1}, {"id": 2}]
result = data[2]["id"] # 哪行错了?
- 预期输出:说明错误原因
- 提示:索引从 0 开始
作业题(30 分钟 - 2 小时)
作业:做一个「电商数据统计工具」
- 需求描述:读取商品和订单数据,输出统计报表
- 功能点:
1. 从 JSON 读取至少 5 个商品
2. 生成至少 3 笔订单(模拟下单)
3. 输出统计:总销售额、总订单数、库存剩余
4. 找出「爆款」:销量最高的商品 - 加分项:
1. 按销售额排序商品
2. 输出 CSV 格式报表 - 验收标准:代码能跑、输出清晰、有中文注释
- 提交方式:评论区贴代码或 GitHub 链接
📚 总结 + 资源
本文学了 3 件事:
1. ✅ 用 class 定义商品、购物车、订单模型
2. ✅ 从 JSON 读取数据,用 Python 处理业务逻辑
3. ✅ 理解了电商核心流程:加购 → 下单 → 扣库存
延伸资源:
- 📖 Python 官方文档 - 类
- 📖 《Python编程:从入门到实践》- 第9章类部分
- 🎬 B站:Python 面向对象编程入门
互动钩子: 你有没有被电商「超卖」坑过?或者抢过秒杀没抢到?评论区聊聊,吐槽最多的老粉我优先回复!
📌 下章预告:Python 里业务逻辑搞明白了,但 JavaScript/TypeScript 写起来啥感觉?下一章我们把电商工具用 TypeScript 重写一遍,顺便加上类型检查——「编译时纠错,比运行时报错爽多了」!

评论(0)