python yaml
### Python与YAML一个老程序员的实用笔记最近在整理项目配置文件时突然想把YAML和Python的那些事儿好好捋一捋。毕竟这个组合太常见了但用不好会坑得人想摔键盘。1. YAML是什么YAML的全称是YAML Ain’t Markup LanguageYAML不是标记语言这个自嘲的名字已经说明了一切。它本质上是一种人类可读的数据序列化格式。和JSON、XML这些同行相比YAML更像是一个强迫症患者写的笔记——通过缩进来表达层级关系用冒号分隔键值对用横线表示列表项。举个最简单的例子假设我们要描述一个人的信息person:name:张三age:28hobbies:-写代码-打游戏-睡觉看到没有连引号都不需要全靠缩进和换行就表达清楚了结构。这种设计哲学很有意思它假设读这个文件的人更关心“内容看起来什么样”而不是“结构怎么解析”。2. 它能做什么在实际项目中YAML最常见的用途有四个配置文件管理这是最普遍的应用。Docker Compose的docker-compose.yml、Ansible的playbook、Kubernetes的deployment配置全部都是YAML格式。它天然适合描述复杂的嵌套配置比如database:host:localhostport:5432pool:min:5max:20timeout:30数据交换虽然JSON在这方面更流行但YAML在某些场景下更有优势。比如多语言翻译文件因为YAML支持多行字符串处理长文本比JSON方便得多。测试数据单元测试里经常需要构造复杂的数据结构。用YAML写测试用例比Python的字典变量更清晰特别是当数据嵌套超过三层的时候。日志解析有些日志系统会输出YAML格式的结构化日志。在调试时直接用Python解析比手动翻日志方便十倍。3. 怎么使用Python里最常用的YAML库是PyYAML。先装包pipinstallpyyaml基础用法很简单就两个函数importyaml# 读取YAML文件withopen(config.yaml,r)asf:configyaml.safe_load(f)# 写入YAML文件data{name:张三,age:28}withopen(output.yaml,w)asf:yaml.dump(data,f,default_flow_styleFalse)这里有个关键点永远别用yaml.load()。它存在安全漏洞会执行任意的Python代码。yaml.safe_load()才是生产环境该用的。处理复杂类型时有些技巧。比如处理时间戳importyamlfromdatetimeimportdatetimedeftimestamp_representer(dumper,data):returndumper.represent_scalar(tag:yaml.org,2002:timestamp,data.isoformat())yaml.add_representer(datetime,timestamp_representer)nowdatetime.now()yaml.dump({time:now})4. 最佳实践写YAML配置文件要像写Python代码一样讲究否则迟早会翻车。缩进用空格打死不用TabYAML对缩进极度敏感而Tab在不同编辑器里表现不一致。有人因为这个bug排查了三天最后发现是编辑器把两个空格显示成Tab的样子。所有的编辑器都应该设置Tab自动转为两个空格。给字符串加引号要谨慎数字或者特殊字符可能会被YAML误解。比如version: 1.0会被解析成数字1.0而version: 1.0才是字符串。当遇到true、false、null这些保留字时不加引号会出大问题# 这个会出问题result:true# 安全写法result:true善用锚点和别名这算是YAML的独门绝技能避免重复配置defaults:defaultsadapter:postgreshost:localhostdevelopment:database:myapp_development:*defaultstest:database:myapp_test:*defaults别嵌套超过三层虽然YAML支持任意深度嵌套但超过三层的配置已经很难人工维护了。这时候应该考虑把长配置拆到多个文件里然后用!include标记需要自定义加载器。5. 和同类技术对比VS JSONJSON的优点在于严格和普及。几乎所有语言都有原生JSON解析器性能也比YAML好差10倍左右。但JSON的可读性差尤其是嵌套结构时括号地狱让人头疼。写个复杂配置{database:{host:localhost,ports:[5432,5433],pool:{min:5,max:20}}}YAML版本database:host:localhostports:[5432,5433]pool:min:5max:20VS XMLXML现在基本被淘汰了。它的冗余程度太高解析也麻烦。但它有命名空间、schema验证这些工业级特性适合那些需要严格数据规范的企业级项目。个人觉得除非是不得不处理旧系统否则没必要用XML。VS TOML这是比较新的格式。它的配置风格类似INI文件加入了表、数组等更丰富的结构。TOML的类型系统比YAML严格没有那些让人头疼的类型推断问题。比如在TOML里写version 1.0永远是字符串。但TOML的表达能力不如YAML处理复杂的多层次结构时比较吃力。实际选择建议如果是个人项目或者小团队YAML是很好的选择。但要注意版本控制——YAML解析时的歧义问题比JSON多得多团队里最好有统一的代码风格规范。如果是做API接口的数据格式劝你别用YAML用JSON。解析性能差异还是次要的关键是前端和各种客户端对YAML的支持太差。