第1周·第2讲|一道综合代码推演

下面是纯 Python 示例,字符串列表只是方便观察,不涉及真实模型调用。

复制代码
def prepare(history):
    messages = history
    request = {"messages": messages}

    messages.append("查询订单")
    messages = ["取消订单"]

    return request


def send(request):
    try:
        raise TimeoutError("请求超时")
    except TimeoutError:
        request["messages"].append("超时记录")
        raise


history = ["系统规则"]
request = prepare(history)

try:
    reply = send(request)
    history.append("请求完成")
except TimeoutError:
    history.append("外层已处理")

假设执行前没有定义过 reply。请先不运行,只回答三点:

  1. 最终 history 和 request["messages"] 分别是什么? 为什么有没有"取消订单"?

答:history是"系统规则",request["messages"]是"系统规则","查询订单";因为messages指向的是另一个列表 与request不同

  1. reply 是否获得了值? "请求完成"会不会加入列表?

答:没有 不会

  1. send() 中的 raise 把异常交给了哪里? 为什么最后能执行"外层已处理"?

答:外层函数 try 与 except 因为符合except TimeoutError的情况 舅执行了 "外层已处理"

答:第 2、3 点答对了;第 1 点对"取消订单"的判断正确,但把共享列表的变化漏掉了。 我们按执行顺序把它串起来。

1. 最终两个列表是什么?

history 和 request["messages"] 最终都指向同一个列表:

复制代码
["系统规则", "查询订单", "超时记录", "外层已处理"]

关键在于这两行:

复制代码
messages = history
request = {"messages": messages}

这里没有复制列表。此时三个位置指向同一个对象:

复制代码
history ─────────────┐
messages ────────────┼──→ ["系统规则"]
request["messages"] ─┘

接下来每一步的变化如下:

执行语句 原列表的内容
messages.append("查询订单") ["系统规则", "查询订单"]
messages = ["取消订单"] 不变,只让局部变量 messages 指向新列表
request["messages"].append("超时记录") ["系统规则", "查询订单", "超时记录"]
history.append("外层已处理") ["系统规则", "查询订单", "超时记录", "外层已处理"]

你说的"messages 指向另一个列表"确实成立,但它发生在重新赋值之后,而且没有解除 history 与 request["messages"] 之间的共享关系。

重新赋值后的关系是:

复制代码
history ─────────────┐
                     ├──→ ["系统规则", "查询订单"]
request["messages"] ─┘

messages ───────────────→ ["取消订单"]

所以"取消订单"不会出现在最终结果里。

2. reply 和"请求完成":你的判断正确。

复制代码
reply = send(request)

Python 要先执行右侧调用,正常返回后才会给左侧赋值。send() 抛出了异常,因此:

  • reply 没有获得值;按题设,它仍未定义。
  • 执行流程跳到匹配的 except,跳过 history.append("请求完成")。

3. raise 的去向:你的理解正确。

这里不带参数的 raise 会重新抛出当前正在处理的异常:

复制代码
send() 抛出 TimeoutError
    ↓
send() 内部 except 捕获它
    ↓
追加"超时记录"
    ↓
raise 重新抛出
    ↓
调用处外层 except TimeoutError 捕获
    ↓
追加"外层已处理"

一个措辞修正:这里是"调用处的外层 try/except",示例中这段代码并没有放在另一个函数里。

这次复核已经确认你理解了异常传播、赋值未完成和异常后的语句跳过 。剩下要巩固的是:重新绑定一个变量,不会改变其他变量对原对象的引用;异常也不会自动撤销此前对列表的修改。

相关推荐
前端的日常26 分钟前
一个人+AI做情侣食谱小程序,0 费用的服务器
前端·后端
小咕聊编程34 分钟前
基于Python的豆瓣电影数据可视化系统构建分析
开发语言·python·信息可视化
计算机魔术师1 小时前
谷歌搜索广告踩刹车,AI广告成为救命稻草
前端
总要学点什么1 小时前
第81篇:数据可视化-PM2.5分布——让圆点的胖瘦替每座城市报出浓度
前端·信息可视化·echarts·cesium·空间分析
IT_陈寒1 小时前
Vue的v-for里用了个临时变量,页面直接挂了
前端·人工智能·后端
hunter_0761 小时前
一次 iOS 真机签名 409 的完整排查:证书、设备、描述文件为什么总是"对不上"
前端
枣把儿1 小时前
开源!公众号排版+一键发布工具懒人版
前端
2501_916007471 小时前
抓包工具功能对比,TraceEagle、Charles、Fiddler、Wireshark、mitmproxy 差别
前端·网络协议·ios·adb·https·fiddler·wireshark
Flynt1 小时前
AI 写的页面一眼假?有人把"假指纹"写成 62 条规则,不用大模型就能跑
前端·ai编程·claude
kyriewen2 小时前
我把 10 道面试题答案真跑了一遍:6 道是错的
前端·javascript·面试