一、Python 数据类型与类型判断
1.1 类型注解与变量定义
SKILL_REGISTRY: dict[str, dict] = {}
- 这是 Python 3.9+ 的类型提示语法
dict[str, dict]表示:键(key)是字符串str,值(value)是字典dict= {}初始化为空字典- 用于提高代码可读性和支持静态类型检查
1.2 isinstance() 类型判断
isinstance(block, dict)
- 不是判断值是否在字典中,而是判断变量
block是否是字典(dict)类型 - 如果
block是dict类型(或其子类实例),返回True;否则返回False - 与
in操作符完全不同:"key" in block才是判断键是否存在
适用数据类型(classinfo 参数):
- 基本类型:
int,float,bool,str,complex - 容器类型:
list,dict,tuple,set - 特殊类型:
bytes,bytearray - 支持多类型联合检查:
isinstance(block, (list, tuple, dict)) - 支持自定义类和继承关系判断
# 多类型检查
isinstance(42, (int, float)) # True
isinstance("hello", Iterable) # True(可迭代对象)
二、字典安全取值
2.1 .get() 方法
meta.get("name", d.name)
meta必须是字典类型(dict),因为.get()是字典的专有方法- 从字典
meta中获取键"name"的值,若不存在则返回d.name作为默认值 d.name是动态表达式,在代码执行时被求值- 值的类型没有限制,可以是任意 Python 对象(字符串、数字、列表、字典、函数等)
与直接索引 meta["name"] 的区别:
| 方式 | 键存在时 | 键不存在时 |
meta.get("name", default) |
返回实际值 | 返回默认值(不报错) |
meta["name"] |
返回实际值 | 抛出 KeyError 异常 |
2.2 getattr() 函数
getattr(block, "type", None)
- 从对象
block中获取名为"type"的属性值 - 属性不存在时返回
None,不会抛出AttributeError - 等价于:
block.type(但更安全)
适用对象类型:
- 几乎所有 Python 对象,包括:
- 类实例(对象)
- 类本身
- 模块(module)
- 内置类型实例(字符串、列表等)
- 自定义对象
# 获取类的静态属性
getattr(MyClass, "class_var", None)
# 获取模块的函数
getattr(math, "sin", None)
# 获取字符串的方法
getattr("hello", "upper", None)()
核心特点:
- 动态性:属性名可以是变量/字符串
- 安全性:提供默认值避免
AttributeError - 通用性:适用于所有 Python 对象
三、序列操作与迭代
3.1 enumerate() 函数
for mi, msg in enumerate(messages):
# mi 是索引(0, 1, 2...)
# msg 是列表中的每个元素值
- 同时获取可迭代对象中的索引和值
- 返回枚举对象,每次迭代产出
(index, element)元组 - 语法:
enumerate(iterable, start=0),可设置索引起始值
适用数据类型(所有可迭代对象):
- 列表(list)
- 元组(tuple)
- 字符串(string)
- 字典(dict,默认枚举键)
- 集合(set)
- 文件对象(file object)
- range 对象
- 生成器表达式(generator)
- 自定义可迭代对象
# 从1开始(常用于行号)
for num, day in enumerate(weekdays, start=1):
print(f"{num}: {day}")
推荐使用 enumerate() 而不是 range(len()),因为代码更清晰、性能更优、适用于生成器。
3.2 sorted() 排序
sorted(blocks, key=lambda p: len(str(p[1].get("content", ""))), reverse=True)
- 返回新的排序后列表,不修改原列表
key:指定排序依据的函数reverse=True:降序排列(从大到小)- 从
blocks中提取content字段的字符串长度,按长度从大到小排序
3.3 any() 判断
any(_block_type(block) == "tool_use" for block in content)
- 判断可迭代对象中是否存在至少一个为真的元素
- 遍历生成器表达式,检查是否至少有一个 block 的类型是
"tool_use" - 短路特性:一旦找到第一个真值就立即返回,不继续遍历
| 情况 | 结果 | 说明 |
| 至少有一个元素为真 | True |
短路返回 |
| 所有元素都为假 | False |
遍历完所有元素 |
| 空的可迭代对象 | False |
特殊行为 |
3.4 列表切片赋值
messages[:] = compact_history(messages)
- 原地替换列表的全部内容,不是清空列表
messages[:]选中列表的全部元素- 等价于:先清空
messages,再将新列表的元素逐个填入
与 messages = compact_history(messages) 的区别:
| 操作 | 效果 | 对外部影响 |
messages = new_list |
创建新列表,局部变量换指向 | 不影响外部引用 |
messages[:] = new_list |
原地修改同一个列表对象 | 所有引用同步更新 |
核心应用场景:AI Agent 的上下文压缩(Context Compaction),确保主循环中的 history 变量同步更新为压缩后的内容。
# 变量作用域:messages 只在 agent_loop 函数内部
# 使用 messages[:] = ... 才能将改变作用到函数外部
def agent_loop(messages):
messages[:] = compact_history(messages) # 外部 history 同步更新
四、Lambda 匿名函数
lambda p: len(str(p[1].get("content", "")))
- 匿名函数,用于定义简单的一次性小型函数
- 语法:
lambda 参数: 表达式 - 自动返回表达式的计算结果
- 常用于
sorted(),filter(),map()等函数的key参数
与 def 定义函数对比:
| 特性 | def 普通函数 |
lambda 匿名函数 |
| 命名 | 必须有函数名 | 无名称 |
| 代码块 | 可以多行 | 只能写单行表达式 |
| 返回值 | 用 return 返回 |
自动返回计算结果 |
五、路径操作
5.1 pathlib.Path.mkdir()
TOOL_RESULTS_DIR.mkdir(parents=True, exist_ok=True)
- 确保目录存在,如果不存在则创建
parents=True:递归创建所有缺失的父目录(相当于 Linux 的mkdir -p)exist_ok=True:目标目录已存在时不报错
四种参数组合:
parents |
exist_ok |
行为 |
False |
False |
创建单层目录,已存在报错 |
False |
True |
创建单层目录,已存在跳过 |
True |
False |
递归创建,但目标必须不存在 |
True |
True |
递归创建,已存在跳过(最常用) |
六、常用代码模式
6.1 兼容多数据格式的取值函数
def _block_type(block):
return block.get("type") if isinstance(block, dict) else getattr(block, "type", None)
- 同时支持字典和对象两种数据格式
- 如果
block是字典:使用.get()安全获取值 - 如果
block是对象:使用getattr()获取属性
6.2 判断是否包含工具调用
has_tool_call = any(_block_type(block) == "tool_use" for block in content)
- 判断 AI Agent 的响应内容是否包含工具调用(Tool Use)
- 结合
_block_type()和any()实现高效判断







