CS50 Finance项目:lookup()未返回字典致buy()函数报错
解决CS50 Finance中lookup()返回None导致的TypeError问题
问题核心
报错TypeError: 'NoneType' object is not subscriptable是因为lookup(symbol)返回了None,代码直接尝试访问result["price"]未做任何边界处理。同时buy函数和lookup函数还存在其他潜在问题,以下是分步修复方案:
修复步骤
1. 处理lookup返回None的边界情况
在buy函数调用lookup后,立即检查返回值有效性,无效则提示用户输入正确股票代码:
result = lookup(symbol) if not result: return apology("无效的股票代码", 400)
2. 验证IEX Cloud API配置
- 确保环境变量
API_KEY已正确设置,且是IEX Cloud的有效密钥(注意区分测试密钥和生产密钥)。 - 替换lookup函数中的API端点:旧的
cloud-sse.iexapis.com已不再适用,更新为当前有效端点:response = requests.get(f"https://cloud.iexapis.com/v1/stock/{urllib.parse.quote_plus(symbol)}/quote?token={api_key}")
3. 修正buy函数中的其他错误
- cash值获取错误:
db.execute返回列表,需提取具体数值:cash_row = db.execute("SELECT cash FROM users WHERE id = ?", session["user_id"]) cash = cash_row[0]["cash"] - shares类型转换与验证:表单获取的shares是字符串,需转为正整数:
try: shares = int(request.form.get("share_num")) if shares <= 0: return apology("购买数量必须为正整数", 400) except ValueError: return apology("请输入有效的购买数量", 400) - SQL语句语法错误:
- INSERT语句不能加WHERE子句,正确插入关联用户的股票记录:
db.execute("INSERT INTO stock(user_id, symbol, name, quantity, price) VALUES (?, ?, ?, ?, ?)", session["user_id"], result["symbol"], result["name"], shares, result["price"]) - UPDATE语句语法修正:
db.execute("UPDATE users SET cash = ? WHERE id = ?", cash - result["price"] * shares, session["user_id"])
- INSERT语句不能加WHERE子句,正确插入关联用户的股票记录:
完整修正后的代码片段
helpers.py(调整API端点)
def lookup(symbol): """Look up quote for symbol.""" # Contact API try: api_key = os.environ.get("API_KEY") # 更新为IEX Cloud当前有效端点 response = requests.get(f"https://cloud.iexapis.com/v1/stock/{urllib.parse.quote_plus(symbol)}/quote?token={api_key}") response.raise_for_status() except requests.RequestException: return None # Parse response try: quote = response.json() return { "name": quote["companyName"], "price": float(quote["latestPrice"]), "symbol": quote["symbol"] } except (KeyError, TypeError, ValueError): return None
app.py(修正buy函数)
def buy(): if request.method == "GET": return render_template("buy.html") else: symbol = request.form.get("symbol").strip() if not symbol: return apology("请输入股票代码", 400) # 处理购买数量 try: shares = int(request.form.get("share_num")) if shares <= 0: return apology("购买数量必须为正整数", 400) except (ValueError, TypeError): return apology("请输入有效的购买数量", 400) # 调用lookup并检查结果 result = lookup(symbol) if not result: return apology("无效的股票代码", 400) # 获取用户当前现金 cash_row = db.execute("SELECT cash FROM users WHERE id = ?", session["user_id"]) cash = cash_row[0]["cash"] # 检查余额是否足够 total_cost = result["price"] * shares if cash < total_cost: return apology("余额不足", 403) # 插入股票记录 db.execute("INSERT INTO stock(user_id, symbol, name, quantity, price) VALUES (?, ?, ?, ?, ?)", session["user_id"], result["symbol"], result["name"], shares, result["price"]) # 更新用户现金 db.execute("UPDATE users SET cash = ? WHERE id = ?", cash - total_cost, session["user_id"]) return redirect("/")
额外注意事项
- 确保
stock表包含user_id字段,用于关联用户和股票记录。 - 测试时优先使用IEX Cloud的测试密钥(以
pk_开头),避免产生不必要的费用。
内容的提问来源于stack exchange,提问作者abdul
相关产品推荐
相关产品推荐

