Skip to content

类型与模型

文件会读写了,给数据加形状。先 typing,再 dataclass,最后 Pydantic。

typing 常用名

python
from typing import Any, Dict, List, Optional, Sequence

rows: list[NewsItem] = ...
config: dict[str, Any]
date_str: str | None = None
PythonTypeScript
Anyany
dict[str, Any] / Dict[str, Any]Record<string, any>
list[NewsItem]NewsItem[]
str | None / Optional[str]string | null
Sequence[NewsItem]readonly NewsItem[]
X = dict[str, Any]type X = Record<string, any>
Callable[[A], Awaitable[B]](a: A) => Promise<B>
python
from typing import Any, Awaitable, Callable

SegmentPayload = dict[str, Any]
SegmentExtractor = Callable[[SegmentPayload], Awaitable[dict[str, Any]]]
ts
type SegmentPayload = Record<string, any>
type SegmentExtractor = (
  payload: SegmentPayload,
) => Promise<Record<string, any>>

from __future__ import annotations 让注解延迟求值,前向引用更安全。JS / TS 没有对等语法,类型本来就会被擦掉。

cast(T, x)x as T,运行时不检查。type(x).__name__x.constructor.name

dataclass:自动构造的 class

字段写法像 interface,效果是能 NewsItem(...) 的 class

python
@dataclass
class NewsItem:
    source_id: str
    item_id: str
    raw_title: str
    metadata: dict[str, Any] = field(default_factory=dict)
    selected: bool = False
ts
class NewsItem {
  constructor(
    public source_id: string,
    public item_id: string,
    public raw_title: string,
    public selected = false,
  ) {}
}
  • 访问用属性:row.raw_title,不是 row["raw_title"]
  • 可变默认值不能写 metadata={},要用 field(default_factory=dict),否则所有实例共享同一个 dict。
  • 不加 @dataclass 就没有自动 __init__,不能按字段名构造。

Pydantic:带校验和说明

比 dataclass 多校验、序列化,以及给模型看的 description

python
from pydantic import BaseModel, Field

class ActionItem(BaseModel):
    task: str = Field(description="可以独立检查是否完成的任务")
    owner: str | None = Field(description="负责人;没有则 null")
ts
// 心智上更接近 Zod schema,不是单纯 interface
const ActionItem = z.object({
  task: z.string().describe('可以独立检查是否完成的任务'),
  owner: z.string().nullable(),
})
概念dataclassBaseModel
目的少写 __init__校验 + 序列化 + 字段说明
转普通 dict自己转item.model_dump()
检查几乎不检查isinstance(result, ActionExtraction)

下一页叠:异步——顶层不能直接 await,还有异步迭代和并发任务。