Python三引号字符串保留缩进空格,易致SQL/JSON错误;应使用textwrap.dedent()剔除公共前缀空格,或inspect.cleandoc()处理docstring,注意避免空格与Tab混用。

用三引号字符串时缩进空格会原样保留
Python 的 ''' 和 """ 多行字符串会把换行和所有空白字符(包括缩进空格)一并存进去,这在函数体或类方法里写文档字符串或 SQL 模板时特别容易导致意外的前导空格。
常见错误现象:print(repr(sql)) 显示字符串开头有多个空格,导致 SQL 执行失败或 JSON 解析报 JSONDecodeError: Expecting value。
- 如果缩进用的是 4 个空格,每行开头都会多出 4 个空格
- 用 Tab 缩进更危险:不同编辑器对 Tab 宽度解释不一致,
repr()可能显示'\t'或等宽空格 - 不能靠手动删缩进——那样会破坏代码可读性,也不符合 PEP 8
用 textwrap.dedent() 剔除公共前缀空格
textwrap.dedent() 会分析所有非空行,找出最小的公共前导空白(只统计空格和 Tab),然后统一删掉。它不碰行首空行、也不动中间或末尾的空格。
使用场景:定义多行配置、SQL 查询、带缩进的模板字符串。
import textwrap
<p>def build_query(user_id):
sql = textwrap.dedent("""\
SELECT name, email
FROM users
WHERE id = %s
ORDER BY created_at DESC
""").strip()
return sql % user_id
</p>
- 必须加
\在第一行末尾,否则第一行换行符会变成字符串开头的空行 - 结尾调用
.strip()是为了去掉末尾换行和可能的空格(dedent不处理尾部) - 注意:如果某行缩进比其他行少(比如只有 2 个空格),它会成为“公共前缀”的上限,其他行只删这么多
用 inspect.cleandoc() 更适合文档字符串
inspect.cleandoc() 是专为 docstring 设计的,行为类似 dedent(),但额外处理了首行缩进逻辑:它会忽略第一行的缩进(哪怕第一行是空行),从第二行开始计算公共前缀。
适用场景:函数/类的 __doc__、需要保持语义清晰的说明文本。
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
import inspect <p>def format_help(): """格式化帮助文本。</p><pre class="brush:php;toolbar:false;">支持以下选项: --verbose 输出详细日志 --dry-run 不执行实际操作 """ return inspect.cleandoc(format_help.__doc__)
- 不用手动加
\,对 docstring 更友好 - 如果 docstring 首行有内容且缩进不一致(比如首行顶格、其余行缩进),
cleandoc仍能合理处理 - 不适用于需要精确控制首行缩进的场景(如生成带缩进的 YAML 片段)
用 f-string + dedent 拼接动态内容要小心换行位置
f-string 本身不支持跨行直接嵌入多行字符串,强行换行会触发语法错误。必须把 f"..." 写在单行内,再用 dedent 处理内部值。
容易踩的坑:在 f-string 中直接换行、或把变量插在 dedent 调用之外。
- ❌ 错误写法:
f"""SELECT * FROM {table}\nWHERE id > {min_id}"""—— 换行符和缩进全被保留 - ✅ 正确写法:先构造干净字符串,再用 f-string 插值,或把插值放在
dedent之后:textwrap.dedent(f"SELECT * FROM {table} ...") - 性能影响:
dedent是纯 Python 实现,对超长字符串(>10KB)会有轻微开销,但日常使用无感
真正麻烦的是混合了缩进风格的字符串(比如空格 + Tab 混用),dedent 和 cleandoc 都会失效——它们按字符逐个比对前缀,Tab 和空格不等价。这种情况下,要么统一缩进风格,要么手动用正则清理。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










