Python配置文件解析:PyYAML从入门到实战踩坑全指南
说实话干 Python 这么久配置文件这块我绕不开的就是 YAML。Docker Compose 的 docker-compose.yml、Ansible 的 playbook、GitHub Actions 的 workflow、Kubernetes 里那一堆资源清单全是 YAML 写的。你在 Python 里想读这些文件、生成这些文件PyYAML 就是最直接、最成熟的答案一条 pip install 装完两个函数跑通剩下的都是技巧问题。这篇文章不绕弯子直接把 PyYAML 从安装、读写、进阶玩法到实战踩坑一次讲透适合刚开始接触 Python 配置处理的新人也适合想补全 YAML 高阶用法的老手。1. YAML 为什么无处不在PyYAML 又是哪一位1.1 配置文件的三次换代从 INI 到 YAML早期写程序配置文件基本是 INI 格式的天下一个节section下面一堆 keyvalue简单直接。但项目一复杂就露馅了——多级嵌套的配置、列表类型的配置INI 表达起来非常吃力硬凑出来的结构又丑又难维护。后来 JSON 成了通用格式机器之间传数据确实方便但对人类不友好花括号、引号、逗号到处都是多一层嵌套就多一屏噪音想在里面写个注释还不行。YAML 的出现就是为了解决给人看的配置这个问题。它用缩进表示层级用冒号分隔键值用短横线表示列表连引号大多数时候都可以不写。我拿同一份配置对比一下你就明白了。JSON 长这样{ server: { host: 0.0.0.0, port: 8000, workers: 4 }, log: { level: INFO, file: app.log } }同样的内容用 YAML 写server: host: 0.0.0.0 port: 8000 workers: 4 log: level: INFO file: app.log信息量完全一样但后者一眼看过去就知道结构是什么。这也是为什么现代 DevOps 生态几乎全部倒向 YAML。简单列个对比对比项JSONINIYAMLTOML可读性一般符号多简单但层级弱强靠缩进表达结构强但普及度低嵌套结构完全支持基本不支持完全支持支持写法略绕注释不支持支持支持支持Python 解析标准库 jsonconfigparserPyYAMLtomllib3.111.2 PyYAML 在 Python 生态里的地位PyYAML 是 Python 生态里历史最久、用的人最多的 YAML 实现。Ansible 的底层配置解析、一些容器 SDK、大量开源框架的 config loader直接或间接都在依赖它。它实现的是 YAML 1.1 规范附带 C 扩展用来加速底层解析API 设计也很 Pythonic读用 load写用 dump就这么简单。后来社区出现了 ruamel.yaml主打保留注释、保留格式的往返读写在一些需要反复人工编辑 YAML 的场景确实更强。但如果你只是想把 YAML 文件读成 Python 对象、把 Python 对象写成 YAML 文件PyYAML 依然是上手成本最低、踩坑资料最全的那个。先把它用熟再谈要不要换更重的库。1.3 安装与第一行代码安装没什么好说的pip install pyyamlLinux 下如果系统同时有 Python 2 的老环境注意用 pip3。装完验证一下版本python -c import yaml; print(yaml.__version__)现在的 PyYAML 主要版本是 6.xPython 3.8 以上的环境直接装最新版就行。装完做一次最简单的读取import yaml data yaml.safe_load(name: demo\nversion: 1.0\n) print(data)输出就是一个普通的 Python 字典{name: demo, version: 1.0}。到这你已经能用 PyYAML 了接下来的内容都是让它更好用、更不容易出错的细节。2. 读写配置的核心操作load 与 dump2.1 读文件一律用 safe_loadPyYAML 读文件的核心函数有两个yaml.load和yaml.safe_load。我的建议非常直接一律用safe_load别碰yaml.load。原因后文的安全红线里细讲这里先记住结论。safe_load只解析 YAML 的常规数据类型——字典、列表、字符串、数字、布尔值、时间不会去实例化任意 Python 对象处理正常配置文件完全够用。实际项目里读配置的标准写法import yaml with open(config.yaml, r, encodingutf-8) as f: config yaml.safe_load(f) print(config[server][port])注意文件名和路径用字符串或 Path 对象都可以但文件打开时一定要显式指定encodingutf-8。不指定的情况下Windows 中文环境会有编码问题Linux 上又依赖默认 locale输出经常让你莫名其妙。safe_load的输入可以是文件对象也可以是 YAML 字符串。两种我都用过项目里读文件用文件对象调试阶段为了省事直接传字符串yaml_str server: host: 0.0.0.0 port: 8000 data yaml.safe_load(yaml_str)提示yaml.safe_load处理的是单个 YAML 文档。如果文件里有多个用---分隔的文档要用yaml.safe_load_all后面专门讲。2.2 写出漂亮配置三个参数必须记牢把 Python 字典写成 YAML 文件用dump或safe_dump。我见过太多人直接yaml.dump(config, f)然后跑来问为什么输出乱七八糟基本都是没调参数。我的标准写法是这样import yaml config { server: {host: 0.0.0.0, port: 8000, workers: 4}, log: {level: INFO, file: app.log}, } with open(config.yaml, w, encodingutf-8) as f: yaml.safe_dump( config, f, allow_unicodeTrue, sort_keysFalse, default_flow_styleFalse, )对应输出server: host: 0.0.0.0 port: 8000 workers: 4 log: level: INFO file: app.log三个参数各司其职缺一个都会出问题参数作用不设会怎样allow_unicodeTrue允许直接输出中文等非 ASCII 字符中文全变成\u5b8c\u6574这种转义序列没法看sort_keysFalse不按键名字母排序默认会把log排到server前面跟你写配置时的顺序不一致default_flow_styleFalse输出块状格式简单字典可能被压成{host: 0.0.0.0, port: 8000}一行可读性归零还有一个参数容易被忽略width。它控制输出行的最大宽度默认 80。如果你的某个值是一长串 URL 或者很长的命令它会把字符串自动折行折行处还会插入额外的缩进看配置文件会觉得莫名其妙。虽然 YAML 语法上完全合法读回来也是原样的字符串但人要维护这种文件就想骂人。不想让它折行就把 width 调大yaml.safe_dump(config, f, allow_unicodeTrue, sort_keysFalse, width1024)另外一个 PyYAML 的经典输出行为嵌套的列表不会在键名下面额外缩进一格ports:下面是顶格的- 8080。这不是 bug是它一贯的块状风格YAML 规范允许这么写读回来语义也完全一样。你要是强迫症犯了非得让它缩进就得换 ruamel.yaml那已经超出 PyYAML 的能力范围了。2.3 字符串与文件对象的切换safe_dump的第二个参数是输出流可以传文件对象也可以省略。省略的时候它会把 YAML 文本作为字符串返回这个用法在拼报文、写接口响应的时候很实用text yaml.safe_dump(config, allow_unicodeTrue, sort_keysFalse) print(text)反过来也一样safe_load既能吃文件对象也能吃字符串所以读写之间其实是可以无缝切换的。我习惯读文件时单独封装一个函数方便统一处理异常和路径from pathlib import Path def read_yaml(path: str | Path) - dict: p Path(path) if not p.exists(): raise FileNotFoundError(f配置文件不存在: {path}) with p.open(r, encodingutf-8) as f: return yaml.safe_load(f)3. 进阶语法锚点、别名与多文档3.1 用 和 * 消除重复配置YAML 有一个 JSON 完全没有的能力锚点anchor和别名alias。在一个文档里你可以给某段内容打个标记然后在后面反复引用它。打标记用名字引用用*名字。最常见的应用场景是多个服务共享同一套默认参数defaults: defaults retry_times: 3 timeout: 30 service_a: : *defaults name: service-a service_b: : *defaults name: service-b这里defaults给{retry_times: 3, timeout: 30}这个映射打了标记是 YAML 的合并键merge key*defaults表示引用刚才的锚点。PyYAML 的 SafeLoader 原生支持这套语法解析结果和你想的一样import yaml data yaml.safe_load(open(services.yaml, encodingutf-8)) print(data[service_a][retry_times]) # 3 print(data[service_b][timeout]) # 30关键是合并的优先级service_b里显式写了timeout: 60的话最终拿到的是 60不会被子映射里的默认值覆盖。这正是配置继承最需要的语义。锚点不只可以用在映射上列表一样能引用admin_ips: admin_ips - 10.0.0.1 - 10.0.0.2 all_ips: - *admin_ips解析后all_ips是一个嵌套列表里面是[[10.0.0.1, 10.0.0.2]]。实际项目里我更多是用锚点来管理测试环境的公共字段比如数据库连接参数、日志级别、超时时间避免在几十个服务配置里复制粘贴同一坨东西。3.2 多文档解析一个文件放多份配置Kubernetes 的清单里一个 yaml 文件经常包含多个资源用---分隔。PyYAML 特别为这种格式提供了safe_load_all--- apiVersion: v1 kind: ConfigMap metadata: name: app-config --- apiVersion: v1 kind: Secret metadata: name: app-secretdocs list(yaml.safe_load_all(f)) print(len(docs)) # 2 print(docs[0][kind]) # ConfigMap注意safe_load_all返回的是一个生成器所以一次性要全部结果就套个list()。如果文件里没有---用load_all也能正常解析结果只有一个文档不会报错。对应的写出多文档用safe_dump_all它接收一个列表每个元素是一个文档yaml.safe_dump_all([config_map, secret], f, allow_unicodeTrue, sort_keysFalse)这招在批量生成 K8s 资源、或者把多份配置导出到一个文件里非常实用。4. 自定义标签让 YAML 直接变出你需要的对象4.1 为什么要自定义标签safe_load只能得到基础的 Python 类型dict、list、str、int、float、bool、datetime。但真实项目里配置文件里经常会有一些不基础的东西。比如金额类字段我不想让它变成 float因为浮点精度会出问题我想要Decimal又比如我想让某个节点直接解析成项目里定义的类实例而不是每次拿到 dict 再手动转。YAML 的标签tag机制就是干这个的。写!标签名给一个节点打标记加载时 PyYAML 会把这个节点交给对应标签的构造器处理。默认的safe_load不认识你自定义的标签需要先注册。4.2 注册 Constructor解析阶段接管注册构造器用add_constructor挂在 SafeLoader 上。我实战里最常用的一个例子是 Decimal 金额import yaml from decimal import Decimal def decimal_constructor(loader, node): return Decimal(loader.construct_scalar(node)) yaml.SafeLoader.add_constructor(!decimal, decimal_constructor)配置文件里这么写price: !decimal 19.99 discount: !decimal 0.15加载后price就是一个Decimal(19.99)后面再做加减乘除不会有0.1 0.2 ! 0.3那种浮点破事。如果是复杂的对象构造器里用construct_mapping把映射转成 dict再丢给自己的类class ServerConfig: def __init__(self, host: str, port: int): self.host host self.port port def server_constructor(loader, node): mapping loader.construct_mapping(node, deepTrue) return ServerConfig(**mapping) yaml.SafeLoader.add_constructor(!server, server_constructor)配置文件server: !server host: 0.0.0.0 port: 8000loader.construct_mapping(node, deepTrue)里deepTrue表示子节点也做深度解析这样如果你的类属性里嵌套了别的自定义类型也能一起变出来。这个参数一开始容易漏漏了之后嵌套结构会拿到半成品是个典型的坑。4.3 注册 Representer写出时还原标签有进就有出。如果你想把Decimal对象再写回 YAML 文件并且保留!decimal标签需要注册对应的 Representerdef decimal_representer(dumper, data): return dumper.represent_scalar(!decimal, str(data)) yaml.SafeDumper.add_representer(Decimal, decimal_representer)这样 dump 出来的内容就是price: !decimal 19.99自定义类的 Representer 用represent_mappingdef server_representer(dumper, obj): return dumper.represent_mapping(!server, {host: obj.host, port: obj.port}) yaml.SafeDumper.add_representer(ServerConfig, server_representer)两个方向都注册之后你的 YAML 读写就完全闭环了加载时自定义标签变成对象写出时对象变回标签。这类注册我建议集中放在项目的一个模块里入口处统一执行避免散落在各个业务代码里造成重复注册或者找不到构造器的尴尬。5. 实战写一个带默认值合并的配置加载器5.1 需求拆解聊完基础串一个真实项目里最常见的场景服务配置管理。需求是这样的项目有一套全量的默认配置不同环境开发、测试、生产只允许写各自不同的那部分。新环境拿到一份空配置文件也能跑起来因为默认值全兜底了。这比每个环境都维护一份完整配置靠谱得多——少写的部分不可能写错。设计很简单代码里内置一份DEFAULT_CONFIG磁盘上的config.yaml只放覆盖项启动时把两份配置做深合并生成最终配置这里的深合并是关键覆盖配置里写了server.port不能把整个server字典都替换掉而应该只改port这一项其他默认项保留。5.2 深合并实现Python 的 dict 没有现成的深合并方法自己写一个也不复杂def deep_merge(base: dict, override: dict) - dict: result dict(base) for key, value in override.items(): if key in result and isinstance(result[key], dict) and isinstance(value, dict): result[key] deep_merge(result[key], value) else: result[key] value return result逻辑一句话讲清楚两边都是 dict 就递归合并否则直接覆盖。这段代码的唯一注意点是开头先复制一份 base不能用result base否则会把默认配置原地改掉第二次加载时就拿不到干净的默认值了。5.3 接入项目定义默认配置和加载函数import yaml from pathlib import Path DEFAULT_CONFIG { server: {host: 0.0.0.0, port: 8000, workers: 4}, db: {host: 127.0.0.1, port: 3306, pool_size: 5}, log: {level: INFO, file: app.log}, } def load_config(path: str | Path) - dict: config deep_merge(DEFAULT_CONFIG, {}) p Path(path) if p.exists(): with p.open(r, encodingutf-8) as f: override yaml.safe_load(f) or {} config deep_merge(config, override) return config注意yaml.safe_load(f) or {}这个细节。空文件读回来是None直接丢进deep_merge会炸or {}把它兜底成空字典空配置文件也能正常跑。使用效果假设config.yaml里只写差异# config.yaml server: port: 8080 log: level: DEBUGconfig load_config(config.yaml) print(config[server][host]) # 0.0.0.0来自默认 print(config[server][port]) # 8080来自覆盖 print(config[server][workers]) # 4来自默认 print(config[db][pool_size]) # 5默认全保留 print(config[log][level]) # DEBUG这套加载器我实际用了很久痛点主要在深合并的边界条件上——比如配置项里如果有列表默认是整个列表替换因为业务上很少需要按索引合并列表。想清楚这个约定行为就可预期了。6. 踩坑实录、安全红线与性能建议6.1 Yes/No 陷阱YAML 1.1 的布尔解析PyYAML 实现的是 YAML 1.1 规范这个版本把yes、no、on、off都当成布尔值。于是你写了enabled: no verbose: off feature_name: on前两个按预期变成False、False但第三个就出事了——feature_name变成了True而不是字符串on。我当时排查过一个线上问题就是有人在配置里写app_mode: off结果代码里拿到的是布尔False跟字符串比较永远不相等。解决方案很简单想让on、no这种词作为普通字符串必须加引号on、no。习惯上只要是看起来像关键词的字符串我都统一加引号。6.2 自动类型转换看着是字符串读出来是数字和时间YAML 会自动识别字面量的类型。写port: 8080读回来是 int写version: 1.0因为加了引号才是字符串没加引号的1.0是 float。同理date: 2024-01-15读回来是datetime.date(2024, 1, 15)不是字符串。版本号、日期、编号这类看起来像数字/日期的字段最容易踩坑。我的经验是凡是业务上必须按字符串处理的字段一律在 YAML 里加引号或者加载后主动调str()别赌解析器的自动识别。6.3 输出格式的四个经典问题写 YAML 文件时遇到的问题基本逃不出下面这张表现象原因处理中文全部变成\uXXXX没开allow_unicodeallow_unicodeTrue键的顺序被打乱sort_keys默认按字母排sort_keysFalse字典被压成一行默认用了 flow 风格default_flow_styleFalse长字符串被奇怪地折行width默认 80调大到 1024 或更高另外还有一个隐蔽问题YAML 文件里的重复键。PyYAML 对重复键不报错而是后写的覆盖先写的。env: dev env: prod读回来env是prod。如果这个文件是别人手工维护的排查起来非常头大。自动化生成配置时我建议写出去之前先检查一遍源字典确保没有重复键。6.4 安全红线为什么不能乱用 yaml.loadyaml.load和yaml.unsafe_load可以反序列化任意 Python 对象。恶意构造的 YAML 里如果带了!!python/object/apply之类的标签解析过程就可能触发任意代码执行。这不是理论风险是真实出现过的攻击路径。所以规则很简单任何来自外部、不可信的 YAML 内容一律用safe_load。只有你完全信任的内容才考虑脱手。配置文件里注册自定义构造器时也要谨慎——你自己加的!server构造器逻辑要简单、可预期别在构造器里执行外部命令。注意PyYAML 5.1 开始直接yaml.load(stream)不传 Loader 会报错并给出提示这就是在逼你明确选择 Loader。永远选SafeLoader或者直接用safe_load。6.5 性能不要在高频热路径上反复解析PyYAML 的解析速度比标准库的 json 要慢一个量级左右。对配置文件这种几 KB、启动时加载一次的场景这完全不是问题但如果你在循环里、在请求处理路径上反复解析同一个 YAML 文件就该考虑缓存解析结果或者干脆把这类高频数据换成 JSON、MessagePack 这类更快的序列化格式。我偶尔也会用yaml.CSafeLoader这种带底层 C 支持的加载器但日常开发中感知不强不要指望它把 YAML 变成 JSON 那样快的格式。最后再分享一个小技巧自定义一个!env标签让配置里直接引用环境变量这在容器化部署的场景特别实用。import os import yaml def env_constructor(loader, node): key loader.construct_scalar(node) return os.environ.get(key, ) yaml.SafeLoader.add_constructor(!env, env_constructor)配置文件里就可以这样写database_url: !env DATABASE_URL api_token: !env API_TOKEN加载后database_url会从当前进程的环境变量里取DATABASE_URL的值取不到就是空字符串。这样我就能把同一份config.yaml提交进代码库而敏感信息全部通过部署平台的变量注入既安全又省事。PyYAML 这东西花半小时读这一篇能给你省下后面无数个查 bug 的夜晚。

相关新闻

claude-mem:为Claude Code注入外部记忆层的RAG实践指南

claude-mem:为Claude Code注入外部记忆层的RAG实践指南

开头用了大半年 Claude Code 做项目,最让我崩溃的不是写不出代码,而是它“忘性太大”。头一天晚上刚跟它把项目结构、端口号、测试规范对齐过,第二天新开一个会话,它连我在requirements.txt里锁过哪个版本的依赖都记不清。每次开工…

2026/10/9 6:45:34 阅读更多 →
Serverless全栈架构与云服务器运维效率革命:从函数部署到Linux自动化排查

Serverless全栈架构与云服务器运维效率革命:从函数部署到Linux自动化排查

最近几年,只要聊到后端架构和运维,必然绕不开Serverless这个名字。我自己的感受是,很多团队起初只是拿Serverless跑一两个小脚本,但真正把它和全栈架构绑在一起,用一套完整的思路去替代部分云服务器运维工作&#xff0…

2026/10/9 6:44:34 阅读更多 →
基于Java的坦克大战毕业设计:Swing实现与碰撞检测避坑指南

基于Java的坦克大战毕业设计:Swing实现与碰撞检测避坑指南

简介:这是一份基于Java Swing的坦克大战游戏开发毕业设计资源,面向计算机相关专业毕业生、Java入门者及游戏开发爱好者,主要解决毕业设计选题、程序实现与论文撰写等需求。压缩包内含毕业论文、完整Java源码和答辩PPT,大小约1.46M…

2026/10/9 6:44:34 阅读更多 →

最新新闻

Solidity英式拍卖合约开发实战:从资金锁定到安全结算

Solidity英式拍卖合约开发实战:从资金锁定到安全结算

最近在带着团队做一个去中心化资产拍卖模块,选型时在英式拍卖和荷兰式拍卖之间纠结了半天,最后还是定了英式拍卖。原因很简单:英式拍卖的交互逻辑和以太坊的Blockchain特性天然契合,出价过程透明、可验证,而且对竞拍者…

2026/10/9 7:21:04 阅读更多 →
游戏对象与资源管理:内存泄漏的因果链与实战治理

游戏对象与资源管理:内存泄漏的因果链与实战治理

1. 这不是教科书里的“对象”和“资源”,而是你写崩溃前最后救你的那行代码“游戏引擎架构深度解析(四):游戏对象与资源管理”——看到这个标题,别急着划走。如果你正在用Unity写UI逻辑时突然卡死、用Unreal加载贴图后…

2026/10/9 7:21:04 阅读更多 →
游戏对象与资源管理:Unity引擎内存泄漏与性能优化实战

游戏对象与资源管理:Unity引擎内存泄漏与性能优化实战

1. 这不是教科书,是我在引擎组熬了七年写下的对象与资源管理手记“游戏对象”和“资源管理”这两个词,听上去像教科书里的章节标题,但实际在项目里,它们就是每天凌晨三点你收到的崩溃日志源头、美术提测时突然炸掉的内存警报、策划…

2026/10/9 7:21:03 阅读更多 →
量子化学如何助力反应工程:从能垒计算到微动力学建模

量子化学如何助力反应工程:从能垒计算到微动力学建模

在反应工程里摸爬滚打久了,你会发现一个很现实的问题:实验室小试跑得飞快的催化剂,放大到工业装置上往往就“不灵了”。床层温度分布不对、副产物突然增多、催化剂寿命断崖式下跌,这些问题的根源,往往不在宏观的传热传…

2026/10/9 7:21:03 阅读更多 →
Uniapp PWA首屏加载优化:预缓存、路由懒加载与资源压缩三板斧

Uniapp PWA首屏加载优化:预缓存、路由懒加载与资源压缩三板斧

1. 先别急着动代码,弄清Uniapp PWA首屏加载的瓶颈在哪1.1 Uniapp H5端首屏加载到底加载了什么去年年中我把一个用Uniapp写的商城项目打包成H5应用,顺手接上了PWA的manifest和Service Worker,觉得既然能装到主屏,体验应该没跑了。结…

2026/10/9 7:21:03 阅读更多 →
UE架构实战:从UObject到GAS、多线程与数据驱动的工程取舍

UE架构实战:从UObject到GAS、多线程与数据驱动的工程取舍

聊到游戏引擎架构,前面几篇我们一直在拆通用概念:场景管理、组件模型、资源生命周期。到了第五篇,终于要落到 UE 实战了。很多人问过我一个问题:学了一堆架构理论,为什么一打开 UE 还是不知道该改哪里?我的…

2026/10/9 7:20:03 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 10:10:36 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →