Python 学习笔记(一)

一、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)类型
  • 如果 blockdict 类型(或其子类实例),返回 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() 实现高效判断
暂无评论

发送评论 编辑评论


				
上一篇