AgentDepthAgent 工程学习指南
输入概念或问题,检索正文和待编写目录。
第一次学习?从 L0 总览开始 →

Python 类型、异常与虚拟环境:把第一个实验做成可复现的项目

我的学习 →

正在读取学习记录…

Python 是一门编程语言。你把指令写进 .py 文件,电脑上的 Python 程序读这个文件并执行它;这个负责执行的程序叫解释器。这里先让它打印一句话,再让它处理一条资料查询。至于虚拟环境、函数、类型和异常,我们会在实际用到它们时逐个解释。

这次的“资料查询入口”接收两个值:查询词“退货规则”和希望返回的条数 3。正常结果是程序接受这条请求;如果把条数换成 True(Python 表示“是”的值),程序就应拒绝,因为“是”不是合理的资料条数。你会先在本机看到最简单的正常输出,再一步步加上这道检查。

第一阶段:让文件里的程序运行起来

先完成安装、选择解释器和打印结果。看到查询词和条数后,再给这个程序增加输入检查。

1. 先确认正在运行哪一个 Python

桌上的蓝色和绿色工具箱各放着一套工具,一人正从蓝色工具箱取工具
图1:两个项目各用自己的工具箱。虚拟环境隔开依赖,但不会限制文件访问权限。

1.1 认识编辑器和终端

编辑器用来写代码,例如 VS Code;终端是输入命令、查看运行结果的窗口。Windows 可以打开 PowerShell,macOS 可以打开“终端”,编辑器里通常也有内置终端。接下来的命令在终端执行,标有文件名的 Python 代码保存到对应的 .py 文件中。

如果窗口里显示 >>>,你进入了 Python 的交互窗口。输入 exit() 回到终端,就可以运行下面的命令。

1.2 安装并确认 Python

课程示例统一使用 Python 3.13.15。3.13.15 是 Python 软件的版本号,类似手机系统的版本号;它不是一个需要另行安装的插件。已经安装 Python 的读者,先查看版本;初次安装的读者按下面的操作即可。

Windows

打开 PowerShell,输入:

PowerShell
py -3.13 --version
py -3.13 -c "import sys; print(sys.executable)"

第一行查看版本,预期显示 Python 3.13.15;第二行显示执行程序的路径,通常以 python.exe 结尾。py 是 Windows 上选择 Python 的启动工具,-3.13 表示选择 3.13 系列。

如果提示找不到命令,或显示的是其他版本,打开 Python 3.13.15 下载页,在 Files 中选择适合电脑的 Windows installer。常见 Intel/AMD 电脑选 64-bit,ARM 电脑选 ARM64。运行安装包,保留 Python launcher,按页面提示完成安装,再重新打开终端执行上面的两行。

macOS

按 Command + 空格,搜索“终端”并打开,输入:

Bash
python3.13 --version
python3.13 -c "import sys; print(sys.executable)"

预期版本也是 Python 3.13.15。如果命令找不到或版本不同,在同一个 Python 3.13.15 下载页选择 macOS 64-bit universal2 installer。下载的是 .pkg 安装包,支持受支持的 Intel 与 Apple 芯片 Mac;双击后按 Continue、Agree、Install 完成安装。

安装后打开“应用程序”里的 Python 3.13 文件夹,双击 Install Certificates.command 完成网络证书设置。重新打开终端,再执行上面的版本检查。Python 官方 macOS 安装说明

-c 表示直接运行引号里的一小段 Python。sys.executable 显示解释器位置,以后遇到“装了包却找不到”,可以用它确认装包和运行代码是否使用同一个解释器。

为什么电脑里可能有多个 Python?

官方安装包和 Anaconda 都可能安装一份 Python;编辑器则可以选择用哪一份运行代码。两个项目也可能分别使用自己的虚拟环境。就像两个人各有一个工具箱:工具箱看起来相似,其中装的工具却可能不同。

1.3 建立学习文件夹与虚拟环境

先创建一个名为 agentdepth-python 的文件夹。Windows 用资源管理器,macOS 用 Finder。把它放在方便找到、可以写入的位置。

进入这个文件夹:

  • Windows:打开文件夹,在地址栏输入 powershell 并回车;已经使用终端的读者,也可以输入 cd ,粘贴带引号的文件夹完整路径,再回车。
  • macOS:在终端输入 cd (后面有一个空格),把 Finder 中的文件夹拖进终端,再按回车。
  • 两种系统都可以输入 pwd 查看当前所在位置。Windows 输入 dir,macOS 输入 ls,可以列出文件。

虚拟环境是项目自己的 Python 工具箱。以后这个项目需要安装额外的库,就放进这个工具箱,便于和其他项目分开管理。

在刚才进入的文件夹里,选择自己的系统执行:

Windows:

PowerShell
py -3.13 -m venv .venv
$env:Path = "$PWD\.venv\Scripts;$env:Path"
python --version
python -c "import sys; print(sys.executable)"

macOS:

Bash
python3.13 -m venv .venv
source .venv/bin/activate
python --version
python -c "import sys; print(sys.executable)"

第一行创建 .venv 文件夹。-m venv 表示运行 Python 自带的虚拟环境工具。第二行让当前终端使用它,随后两行确认版本和路径:Windows 路径里会有 .venv\Scripts\python.exe,macOS 路径里会有 .venv/bin/python。

选择环境后,两种系统都可以用 python 运行后面的例子。新开终端时,先回到学习文件夹,再执行对应系统的第二行命令。

先试着输出一句话:

Bash
python -X utf8 -c "print('你好,资料助手')"

看到 你好,资料助手,就说明终端已经能执行 Python。print 的作用是把结果显示出来;下一步把代码保存到文件中。

以后安装库时使用 python -m pip,就会安装到当前选择的环境。例如 python -m pip --version 能查看安装工具的版本和位置。虚拟环境主要管理项目依赖,程序仍按当前用户的权限访问文件。Python 虚拟环境文档

2. 用字典保存查询词和条数

先写一个能看见结果的文件

在学习目录新建 first_task.py,保存下面的代码。编码选择 UTF-8。

保存为 first_task.py:

Python
"""用字典保存查询任务,再分别打印查询词和条数。"""
task = {"query": "退货规则", "limit": 2}
print(task["query"])
print(task["limit"])

运行 python -X utf8 first_task.py,先显示 退货规则,再显示 2。

第一行用 = 把一个值交给名字 task,这个名字叫变量。花括号里的对象叫字典,通过键寻找值:"query" 是键,"退货规则" 是它的值。task["query"] 就是取出该值;print(...) 把括号内的结果显示出来。把查询词改成 退款到账时间,保存后再次运行,你应该看到新文字。如果还是旧文字,先检查是否保存、是否运行了另一个目录的同名文件。

现在回到资料助手的任务:

先给资料查询准备一个任务,包含查询词和返回条数:

Python
task = {"query": "退货规则", "limit": 2}

query是搜索文字,limit是最多返回几条结果。这里人为规定:只允许这两个字段,query去掉两端空白后为1到80个字符,limit是1到5的整数。这些取值来自资料助手的查询规则。

数据Python中的含义本任务是否接受
"2"字符串,内容是一个字符2不作为条数接受
2整数接受
2.0浮点数,即使数值等于2本契约拒绝
True布尔值不作为条数接受
None空值对象不作为查询文字接受
" "非空字符串,但内容全是空白清理后拒绝

为什么不把所有输入都转成字符串或整数?因为自动转换可能藏住错误。str(None)会产生文字"None",却不说明用户真的查询了这个词;把布尔值转成整数也可能把一个开关误当条数。先约定接受哪些形式,再决定是否转换。

注意Python字典不是JSON文本。字典是运行中的对象,JSON是交换数据的格式。后面的HTTP与JSON篇会讨论序列化;这里用直接构造的字典,让注意力留在类型与契约上。

第二阶段:检查输入,处理错误

接下来把处理步骤写成函数。仍然使用刚才的查询词和条数,逐步加入类型、取值范围和异常处理。

3. 类型提示与运行时检查

函数是有名字的一段可重复使用的步骤。def 定义函数,括号里的 query 是调用者交给它的参数;return 把结果交回调用者。冒号后的代码需要缩进,这里统一用四个空格。同一级步骤缩进要一致,不能随意混用 Tab 和空格。

下面的 echo_demo.py 接收一个参数并返回它。先看类型提示如何写,再保存完整文件运行。

query: str和-> str描述我们期望的输入、输出。它们帮助读代码,也可以供静态检查工具使用。但Python解释器不会仅凭这些标注自动拒绝传入的数字。这一点在typing官方文档中有明确说明。

程序打印 123:实际拒绝错误类型,需要在函数里写检查。

保存为 echo_demo.py:

Python
"""观察函数收到数字123时会返回什么,再理解类型标注的用途。"""
def echo(query: str) -> str:
    return query

print(echo(123))

保存后在学习目录运行 python -X utf8 echo_demo.py,预期显示 123。这次运行说明类型提示本身没有拦住数字输入。

这里要分清两种检查:静态检查在不实际跑业务的情况下分析代码,运行时检查则看这一次真正拿到的值。外部输入可能来自用户、文件或服务,不能因为函数签名写了类型,就认为输入已经可信。

Java读者可以把类型提示理解为给函数写的一份接口说明,但它不像 Java 编译器那样直接挡住传错类型的调用。TypeScript类型也无法替代运行时对网络数据的检查。三种语言的共同问题是:外部输入到了程序边界,仍要验证实际值。

4. 整理查询词,检查条数

先只处理查询词。新建同目录的 query_demo.py,保存并运行下面的完整例子:

Python
def clean_query(query):
    if not isinstance(query, str):
        raise TypeError("查询词需要是文字")
    return query.strip()

print(clean_query("  退货规则  "))

运行 python -X utf8 query_demo.py,会得到 退货规则。isinstance(query, str) 检查是否是字符串,也就是文字;strip() 去掉两端空白,保留中间内容。把最后一行的输入改成 123 再运行,程序会在类型检查处报告 TypeError,表示传来的数据种类不对。恢复文字后,它又能正常返回。

现在加上条数和字段检查。先将下方完整代码保存为 foundations.py,随后再看核心函数的摘录;对照刚才的短函数,观察检查怎样从一个值扩展到整个任务:

保存为 foundations.py:

Python
"""检查查询词和条数,整理成程序能使用的任务参数。"""
import json
import sys

def normalize_task(raw: dict) -> dict:
    if not isinstance(raw, dict):
        raise TypeError('task must be a dict')
    if set(raw) != {'query', 'limit'}:
        raise ValueError('only query and limit are allowed')
    query, limit = raw['query'], raw['limit']
    if not isinstance(query, str):
        raise TypeError('query must be a string')
    # True/False 表示开关;条数需要整数,使用 type 精确区分这两种输入。
    if type(limit) is not int:
        raise TypeError('limit must be an integer, not bool')
    query = query.strip()
    if not query or len(query) > 80:
        raise ValueError('query must contain 1..80 characters')
    if not 1 <= limit <= 5:
        raise ValueError('limit must be between 1 and 5')
    return {'query': query, 'limit': limit}

def run_task(raw: dict) -> dict:
    try:
        task = normalize_task(raw)
    except (TypeError, ValueError) as error:
        return {'status': 'rejected', 'error_type': type(error).__name__}
    return {'status': 'ready', 'task': task}

if __name__ == '__main__':
    print('Python:', sys.version.split()[0])
    for name, raw in [
        ('valid', {'query': ' 退货规则 ', 'limit': 2}),
        ('wrong_type', {'query': 123, 'limit': 2}),
        ('empty', {'query': ' ', 'limit': 2}),
        ('bool_count', {'query': '退货', 'limit': True}),
    ]:
        print(name, json.dumps(run_task(raw), ensure_ascii=False))

先检查容器,再检查字段,再检查类型,最后检查值的范围。顺序有原因:不是字典时不该按字典取字段;query不是字符串时不该调用.strip()。把顺序写清楚,错误就更接近真正原因。

代码写法读成一句话为什么放在这里
if not isinstance(raw, dict)如果 raw 不是字典后面的按键取值才有意义
set(raw)收集字典里全部键,不关心顺序对比允许的字段集合
query, limit = ...分别给两个变量赋值之后逐个检查
query.strip()得到去掉两端空白的新字符串不把纯空格当查询词
len(query)计算字符串长度限制任务输入大小
raise ValueError(...)停止本函数的正常执行并报告值错误不能带着不合法数据继续做事
return {...}将一个新字典交回调用方校验和整理通过后再使用

跟踪正常输入 {"query":" 退货 ","limit":2}:它是字典→键恰好两个→类型合适→查询词变成“退货”→条数在范围内→返回新字典。再跟踪 {"query":123,"limit":2}:检查到 query 类型时就抛出异常,不会继续执行 .strip()。运行后,把接受和拒绝结果分别对应到这两条路径。

set(raw)取得字典的键集合。要求与两个字段完全一致,同时拒绝缺字段和多字段。这是本例的严格契约;有些服务允许扩展字段,不能把本例规则当成所有API的要求。

字符串用isinstance,条数却用type(limit) is int,是有意的。Python 布尔类型文档说明bool是int的子类,isinstance(True, int)会得到True。本任务不接受布尔条数,所以选择精确类型检查。它也拒绝其他整数子类;若业务需要这些类型,应另行设计,而不是机械照搬。

最后返回一个新字典,原始 raw 保持原样。调用者拿到整理后的任务,就可以交给下一步搜索;原始输入则留着用于比较。

5. 用异常定位和处理失败

raise表示当前函数不能按约定完成工作。调用者可以处理已知失败,也可以让错误向外传播。选择在哪层捕获,比把所有代码包进一个大try更重要。

先认识下面四个关键字:try 中放可能发生已知失败的步骤;except 指定哪些异常由这里处理;as error 给捕获到的错误取名;没有错误时会跳过 except,继续运行后面的正常返回。异常会中断当前的正常执行路径,不是普通的打印语句。

Python
def run_task(raw: dict) -> dict:
    try:
        task = normalize_task(raw)
    except (TypeError, ValueError) as error:
        return {"status": "rejected", "error_type": type(error).__name__}
    return {"status": "ready", "task": task}

这里try只围住输入规范化,捕获的是已预期的类型和值错误。没有使用except Exception: pass:静默吞掉异常会把失败变成没有解释的空结果。也没有把异常转换成“成功”。状态ready表示可以进入后续步骤,rejected表示输入被拒绝。

此处不把原始输入拼到错误结果中,避免未来输入包含敏感内容时直接回显。真实项目可能需要更细的字段错误码;这里先学会把预期输入失败与程序错误分开。异常传播与处理语法见Python异常教程。

一个容易误用的地方是把真实搜索也放进同一个try,然后把搜索里的TypeError一律解释成用户参数错误。那样会掩盖内部缺陷。之后加入工具时,应给执行阶段建立自己的错误边界。

第三阶段:对照结果,用测试检查规则

程序已经写好。先观察四种输入的结果,再用测试自动检查这些规则;以后改代码时,也能重复同一组检查。

6. 运行四个输入,逐项看结果

把程序和test_foundations.py放到第1节创建.venv的学习目录,文件名不要改;终端也切换到这个目录。不要把文件留在下载目录,却在另一个目录执行命令。目录应当是:

完整代码:test_foundations.py
Python
# 核对Python 类型、异常与虚拟环境的正常结果和错误分支;断言失败时会显示对应的测试。
import unittest
from foundations import normalize_task, run_task

class FoundationTests(unittest.TestCase):
    def test_valid(self):
        self.assertEqual(normalize_task({'query': '  退货规则 ', 'limit': 2}), {'query': '退货规则', 'limit': 2})
    def test_query_type_validation(self):
        with self.assertRaises(TypeError):
            normalize_task({'query': 123, 'limit': 2})
    def test_bool_is_not_limit(self):
        with self.assertRaises(TypeError):
            normalize_task({'query': '退货', 'limit': True})
    def test_empty(self):
        with self.assertRaises(ValueError):
            normalize_task({'query': ' ', 'limit': 2})
    def test_range(self):
        with self.assertRaises(ValueError):
            normalize_task({'query': '退货', 'limit': 0})
    def test_extra(self):
        with self.assertRaises(ValueError):
            normalize_task({'query': '退货', 'limit': 2, 'admin': True})
    def test_input_unchanged(self):
        raw = {'query': ' 退货 ', 'limit': 2}
        normalize_task(raw)
        self.assertEqual(raw['query'], ' 退货 ')
    def test_business_failure(self):
        self.assertEqual(run_task({'query': '', 'limit': 2})['status'], 'rejected')

if __name__ == '__main__':
    unittest.main()
TXT
你的学习目录/
  .venv/
  foundations.py
  test_foundations.py

先运行演示程序:

PowerShell
python -X utf8 foundations.py

程序先显示解释器版本,随后输出四条结果:

TXT
valid {"status": "ready", "task": {"query": "退货规则", "limit": 2}}
wrong_type {"status": "rejected", "error_type": "TypeError"}
empty {"status": "rejected", "error_type": "ValueError"}
bool_count {"status": "rejected", "error_type": "TypeError"}
用例预期状态原因
两端有空格的合法查询,limit为2ready去空白后保留正常内容
query为123rejected / TypeError查询类型不符合约定
query只有空格rejected / ValueError类型正确但有效内容为空
limit为Truerejected / TypeError布尔不是允许的条数

四个输入分别检查去空白、文字类型、有效内容和整数条数。它们对应四条规则,可以沿函数逐项找到判断位置。

接着运行测试:

PowerShell
python -X utf8 -m unittest test_foundations.py -v

每项末尾应显示 ok,最后是 Ran 8 tests 与 OK。unittest 是 Python 自带的测试工具,-v 让它逐项显示检查结果。看到 OK 后继续下面的条数实验;如果出现 FAIL 或 ERROR,按测试名找到对应规则。若提示找不到文件,运行 dir 确认当前目录里有这两个文件。

在同目录新建 try_limit.py,保存下面的代码:

Python
from foundations import run_task

print(run_task({"query": "退货规则", "limit": 5}))
print(run_task({"query": "退货规则", "limit": 6}))

运行 python -X utf8 try_limit.py。5在允许范围内,状态为 ready;6超过上限,状态为 rejected,错误类别为 ValueError。两个调用只改变条数,就能清楚观察上限检查。

7. 测试应该保护哪一条约定

上方的测试代码包含8个方法,分别检查合法结果、查询类型校验、布尔条数、空查询、范围、多余字段、原始输入不变,以及调用边界返回拒绝状态。查询类型测试检查数字输入会被拒绝;第3节的 echo 例子则展示类型提示与实际检查的区别。测试类和断言写法可对照 Python unittest 官方文档。

Python
def test_input_unchanged(self):
    raw = {"query": " 退货 ", "limit": 2}
    normalize_task(raw)
    self.assertEqual(raw["query"], " 退货 ")

这个测试保护“原始输入保持不变”这一约定。如果有人为了少写一行改成raw["query"] = raw["query"].strip(),测试就会指出行为变化。

你可以在自己的副本做一次反向实验:把type(limit) is not int改成not isinstance(limit, int),再运行测试。布尔条数测试应失败,因为True会进入1到5的范围。随后恢复原实现。主动让测试失败一次,能确认它真的检查到了你想保护的行为。

还可以增加一个超过80字符的查询:它会在长度检查处被拒绝。测试文件中的每个断言,都应该对应一条你希望长期保持的行为。

8. 常见报错,按顺序排查

现象先检查处理办法
找不到python命令Python是否安装,终端能否找到它回到第1节,选择解释器并重新打开终端
找不到foundations模块两个程序文件是否同目录,命令工作目录是否正确把文件放在一起,切到该目录再运行
同一命令在IDE能跑,终端不能比较sys.executable和工作目录将两边改为同一解释器和学习目录
Unicode显示异常终端显示设置、文件UTF-8和-X utf8用UTF-8保存文件,再按文中的命令运行
程序退出码0但某条任务rejected查看任务状态;示例把输入拒绝作为结果打印按error_type查对应规则,修改输入后重跑

错误定位至少分三层:环境能否启动、程序逻辑能否执行、业务输入是否被接受。先判断落在哪一层,再改对应代码。后面的HTTP状态码和模型输出检查会继续复用这个习惯。

9. 自测与实践作品

课后练习展开习题收起习题
题1:query: str已经写了,为什么还要isinstance?

类型提示描述预期,解释器不会仅凭标注拒绝外部数字输入。运行时检查针对本次真实值,两者职责不同。

题2:为什么不把所有异常都返回rejected?

未预期的程序错误或工具故障不一定是输入问题。统一改写会误导排错。本例只在输入边界捕获约定内的两类错误。

题3:虚拟环境能阻止示例读取你的私人文件吗?

不能。它隔离包环境,不构成文件访问沙箱。陌生代码仍需审查,实验不使用真实凭据和私人材料。

扩展练习:为资料增加分类(已跑通前面的例子后再做)

增加 category 字段,只允许 policy 和 manual,保留原有 query 和 limit 规则。下面用测试类组织多个检查,比前面的单次调用多一步;可以先读完总结,熟悉测试后再回来。

第一次写测试,可以按下面的顺序动手:

  1. 在学习目录中新建 category-practice 文件夹,复制 foundations.py 和 test_foundations.py 进去;之后只编辑这两个副本。
  2. 在程序文件找到 normalize_task,先写下新的字段契约。既然增加了必填字段,原来只允许两个键的集合也要调整,不能只在末尾多写一个判断。
  3. 在测试文件找到 class FoundationTests(unittest.TestCase):。新方法放在该类内部,与已有的 def test_valid 对齐,方法名以 test_ 开头。方法内部再缩进四个空格。
  4. 先仿照下面的方法补一个原契约的缺字段测试,跑通后再写类别测试。这个片段应插入测试类内,不是新建一个文件单独运行:
Python
    def test_missing_query(self):
        with self.assertRaises(ValueError):
            normalize_task({"limit": 2})

self.assertRaises(ValueError) 表示接下来的调用应该抛出值错误;没有抛出就会失败。self.assertEqual(实际值, 预期值) 则比较两者是否相等。self 是测试工具调用类中方法时传入的实例,这里可以先沿用该写法,暂不要求掌握面向对象设计。

  1. 新契约中的正常输入应包含 category;原来验证其他规则的测试也应补合法类别,避免全部提前卡在缺字段检查,根本没测到目标规则。调整 test_valid 的预期返回值,检查程序有没有保留类别。
  2. 在已经选择虚拟环境的终端中进入 category-practice,执行 python -X utf8 -m unittest test_foundations.py -v。

先让一个新测试因尚未支持类别而失败,再补实现让它通过。FAIL 表示某个预期未满足,ERROR 通常表示执行测试时发生了未处理的异常;两者都需要查看具体测试名、异常及源码位置,对照需求检查实现和预期,修复后再重跑同一测试。

改完后检查三件事:合法类别能正常返回;未知类别会给出明确错误;原来的条数检查仍然有效。能解释这三种结果,就掌握了这次修改的关键。保留代码副本,方便以后回看。

讨论题:产品希望允许limit传字符串"2"。你会拒绝还是转换?合理答案不只有一个,但必须说明转换发生在哪里、"2.5"和空字符串怎么办,以及契约改变后哪些测试要更新。

下面六题会保存到本地练习记录,分别检查解释器、文件位置、类型提示、异常处理、代码修改和环境排错,方便之后按 L0-python 筛选复习。

6 道练习 · 客观题规则评分 · 其余题目待批改

正在读取本地记录…

不调用模型,不执行代码。简答、代码和场景题仅保存答案并展示自查标准,不生成评分、徽章或认证。输入内容不会自动保存,请点击提交;不要填写个人信息或密钥。

练习 1 / 6 · v1.0.0

选择题 · 怎样确认用了项目环境?

你已在学习目录创建 .venv。下面哪项最能确认这次执行用的是它的解释器?

对应知识点:L0-python

选择一个答案
练习 2 / 6 · v1.0.0

场景题 · 下载了文件却找不到

foundations.py 保存在下载文件夹,你却在 agentdepth-python 文件夹执行它,终端提示找不到文件。解释原因,给出在 PowerShell 中检查和修正的步骤。

对应知识点:L0-python

练习 3 / 6 · v1.0.0

选择题 · 类型提示会自动拦截错误输入吗?

函数参数写成 `query: str`,调用时传入数字。Python 解释器通常会怎样?

对应知识点:L0-python

选择一个答案
练习 4 / 6 · v1.0.0

简答题 · 为什么不能吞掉所有异常?

请解释 `except Exception: pass` 会给输入校验和 Agent 工具调用带来什么问题。

对应知识点:L0-python

练习 5 / 6 · v1.0.0

代码题 · 增加一个输入字段

在 `normalize_task` 中增加 `category` 字段,只允许 `policy` 和 `manual`。写出三个测试:正常、未知值、类型错误。

对应知识点:L0-python

练习 6 / 6 · v1.0.0

场景题 · IDE 能跑,终端不能跑

同一项目在 IDE 能运行,在终端提示找不到模块。请给出排查顺序。

对应知识点:L0-python

10. 总结与后续阅读

把运行过程归纳成三点:

  • 同一个 .py 文件由哪个解释器运行,取决于你实际调用的路径。项目里的 .venv 帮你固定解释器和包目录。
  • query: str 表示作者希望它是字符串;真正拒绝数字输入的是 normalize_task 中的运行时检查。run_task 再把预期错误变成可读的拒绝结果。
  • limit=5 得到 ready,limit=6 在范围检查处被拒绝。能找到这两个结果对应的代码,就学会了把规则落实为检查。

进一步了解这两处机制可读 Python venv 和 类型提示。

后续研究顺序:先读 CPython 的教程和标准库测试组织;熟悉环境后看 uv 的项目管理;需要更丰富的数据检查时看 Pydantic。

下一篇:HTTP、REST与JSON。你不必先掌握所有Python高级特性,但应能独立跑通这里,并解释每个被拒绝的输入为什么被拒绝。

参考资料

参考资料:虚拟环境 venv、类型提示 typing、异常教程、unittest。

图片查看器
100%

文章配图 · 按 Esc 关闭