
本文介绍在利用 Python ast 模块动态生成代码时,如何获得美观、可读性强的多行字典格式输出(如每键值对独占一行、双引号、正确缩进),并说明原生 AST 的局限性及推荐的工程化解决方案。
本文介绍在利用 python `ast` 模块动态生成代码时,如何获得美观、可读性强的多行字典格式输出(如每键值对独占一行、双引号、正确缩进),并说明原生 ast 的局限性及推荐的工程化解决方案。
Python 的 ast 模块擅长构建和操作抽象语法树,但其核心设计目标是语义正确性与可执行性,而非代码风格或可读性。正如示例中所见,ast.unparse() 生成的是功能等价但紧凑的单行字典表达式:
my_awesome_properties = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
而我们期望的是符合 PEP 8 和现代 Python 工程实践的多行格式:
my_awesome_properties = {
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
⚠️ 关键事实:ast 模块本身不提供控制换行、缩进、引号风格等格式化能力。ast.unparse() 的输出行为由 Python 解释器内部实现决定,且在不同版本中可能变化;它不会保留你手动设置的 lineno 或 col_offset 来影响格式——这些字段主要用于错误定位,而非渲染控制。
✅ 推荐方案:后处理 + 格式化工具(如 black)
最可靠、生产就绪的方式是:先用 ast.unparse() 生成合法代码字符串,再交由专业代码格式化工具美化。
步骤如下:
- 安装
black:pip install black - 将 AST 转为字符串,传入
black.format_str() - 指定
mode=black.FileMode()(默认即适用于模块级代码)
import ast
import black
# 构建 AST(同原问题)
my_awesome_properties = [
(ast.Constant(value="key1"), ast.Constant(value="value1")),
(ast.Constant(value="key2"), ast.Constant(value="value2")),
(ast.Constant(value="key3"), ast.Constant(value="value3")),
]
my_awesome_properties_dict = ast.Dict(
keys=[key for key, value in my_awesome_properties],
values=[value for key, value in my_awesome_properties]
)
my_awesome_properties_assignment = ast.Assign(
targets=[ast.Name(id='my_awesome_properties', ctx=ast.Store())],
value=my_awesome_properties_dict
)
my_awesome_module_node = ast.Module(
body=[my_awesome_properties_assignment],
type_ignores=[]
)
# 第一步:生成原始代码字符串
raw_code = ast.unparse(my_awesome_module_node)
# 第二步:用 black 格式化(自动启用双引号、多行字典、4空格缩进等)
formatted_code = black.format_str(raw_code, mode=black.FileMode())
print(formatted_code)
✅ 输出将严格匹配预期:
my_awesome_properties = {
"key1": "value1",
"key2": "value2",
"key3": "value3",
}
? 提示:
black默认会在末尾添加逗号(trailing comma),提升 Git diff 可读性与后续增删便利性,这是强烈推荐的实践。
? 替代思路(不推荐用于生产)
- 手动拼接字符串(牺牲 AST 安全性与可维护性);
- 使用
astor(已归档)或astpretty(仅调试用)——均不保证格式稳定性; - 自定义
ast.NodeVisitor实现unparse——开发成本高、易出错、难兼容。
总结
-
ast是构建代码的“骨架引擎”,不是“排版工具”; - 格式化应交给专精此领域的工具(如
black、autopep8或yapf); - “生成 → 格式化”两阶段流水线是 Python 元编程中的最佳实践,兼顾正确性、可读性与可维护性。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











