Python格式化
vscode的python格式化让人大吃一惊, 摸不着头脑.
明显的坑
- 截止今天, 你在vscode的setting里面直接搜索defaultFormatter, 他给你显示的是none, 然后, 你切换为文本json格式, 再搜索, 欧豁…能搜出来4个.
- 如果你是pip安装, 然后vscode之中是否执行以及如何执行就非常复杂.
- 某些时候会被直接执行, 取决于vscode的版本, 时不时就抽风随机执行一个你安装个格式化器.
- 某些时候如果vscode没找到setting对应的插件, 他会到路径里面找对应的格式化器.
- 格式化器有各种执行的可能性
- 插件执行, 这个最稳, 如果装了插件一定执行
- 路径执行/pip安装执行, 这两个不一定
- git的各种环节执行
- 全局格式化器, prettier
各种格式化
# | 市场里的显示名称 | 插件 ID(settings.json 中看到的) | 作用 | 是否官方 | 备注 |
---|---|---|---|---|---|
1 | Black Formatter | ms-python.black-formatter |
按 Black 规则整份代码重新排版 | ✅ 微软官方 | 最流行,一行改到底 |
2 | YAPF Formatter | eeyore.yapf |
按 YAPF/Google 规则格式化 | ❌ 社区 | 可高度自定义风格 |
3 | autopep8 | ms-python.autopep8 |
把 pycodestyle 报出的格式问题自动修好 | ✅ 微软官方 | 修复力度比 Black 轻 |
4 | isort | ms-python.isort |
只整理 import(排序、折叠/展开) | ✅ 微软官方 | 常和 Black 一起用 |
5 | Ruff | charliermarsh.ruff |
超快 linter + formatter,可替代 Black+isort | ❌ 社区 | 2023 后起之秀 |
6 | Python(主扩展) | ms-python.python |
内置「fallback」格式化器(Jedi 或退调 PATH 工具) | ✅ 微软官方 | 没装上面 1-5 时才会用到 |
使用isort和yapf
// vsocde的 setting这么写
"[python]": {
"editor.tabSize": 2,
"editor.insertSpaces": true,
"editor.formatOnType": false,
"editor.formatOnSaveMode": "modifications",
"editor.formatOnSave": true,
"editor.defaultFormatter": "eeyore.yapf",
"editor.codeActionsOnSave": {
"source.organizeImports": "always" // 由 isort 负责
}
}
# .style.yapf这么写
[style]
based_on_style = pep8
column_limit = 999
split_penalty_after_opening_bracket = 7000
split_penalty_for_added_line_split = 7000
# split_penalty_excess_character = 7000
split_penalty_import_names = 0
# 合并多行
join_multiple_lines = true
# 参数拆分为多行
allow_multiline_lambdas = false
# 右括号对齐
dedent_closing_brackets = true
# 参数前换行
split_before_named_assigns = false
# 复杂推导式换行
split_complex_comprehension = false
# 字典换行
each_dict_entry_on_separate_line = false
# Import语句相关设置
coalesce_brackets = true
force_multiline_dict = false
allow_split_before_dict_value = false
# isort配置 --profile black 或 multi_line_output = 0
# pyproject.toml 或者 .sort.cf
[settings]
profile = black
line_length = 999
multi_line_output = 0
这个世界终于清净了.
然后空行的空格和ai配合, 导致无比艰难
yapf会自动删除所有空行中的空格, 然后, 每次都要tab到位才能输入. 此时ai不停地提示联想句子…..
//vscode setting加这三句
"files.trimTrailingWhitespace": false, // 别删
"editor.insertSpaces": true,
"editor.autoIndent": "full" // 空行回车即自动缩进
//全文在下面
"[python]": {
//"editor.formatOnType": true,
"editor.tabSize": 2,
"editor.insertSpaces": true,
"editor.formatOnType": false,
"editor.formatOnSaveMode": "modifications",
"editor.formatOnSave": true,
"editor.defaultFormatter": "eeyore.yapf",
"editor.codeActionsOnSave": {
"source.organizeImports": "always" // 由 isort 负责
},
"files.trimTrailingWhitespace": false, // 别删
"editor.autoIndent": "full" // 空行回车即自动缩进
},
# yapf只能做到这一步
# 禁止删除“行尾/空行”空格
trim_whitespace_in_blank_lines = false
# isort也要改
# 关键:保留空行里的空格
ensure_newline_before_comments = false
remove_redundant_aliases = false
# 5.x 新选项
treat_all_comments_as_code = true
因此要换autopep8
//setting里面替换这一句
"editor.defaultFormatter": "ms-python.autopep8", //eeyore.yapf",
# 和isort一起的配置文件: pyproject.toml
[tool.autopep8]
max_line_length = 999
indent_size = 2
hang_closing = false
ignore = # 不想修的 PEP 8 错误码
#E133,E226,E302,E305,E704,W503,W504
# 关键:给空行也插入缩进空格(需要 autopep8 ≥ 2.0)
indent_blank_lines = true
即便如此, vscode依旧顽强的要删除空行的空格, 因此排查问题
autopep8 --version
autopep8 2.3.2 (pycodestyle: 2.12.1)
autopep8 --indent-blank-lines --diff s9log.py
usage: autopep8 [-h] [--version] [-v] [-d] [-i] [--global-config filename] [--ignore-local-config] [-r] [-j n] [-p n] [-a] [--experimental] [--exclude globs] [--list-fixes] [--ignore errors] [--select errors] [--max-line-length n] [--line-range line line]
[--hang-closing] [--exit-code]
[files ...]
autopep8: error: unrecognized arguments: --indent-blank-lines
autopep8 --indent-blank-lines --ignore W293,W503,W504,C0303,C2401 -i s9log.py
usage: autopep8 [-h] [--version] [-v] [-d] [-i] [--global-config filename] [--ignore-local-config] [-r] [-j n] [-p n] [-a] [--experimental] [--exclude globs] [--list-fixes] [--ignore errors] [--select errors] [--max-line-length n] [--line-range line line]
[--hang-closing] [--exit-code]
[files ...]
autopep8: error: unrecognized arguments: --indent-blank-lines
查看output
- python里面只有:
- 2025-09-05 11:04:38.382 [info] Discover tests for workspace name: code - uri: /Users/bergman/my2024/X/oh-my-project/技术/脑图_keydog_贱狗/code/s9log.py
- autopep8里面有:
- 2025-09-05 11:04:38.048 [info] /Users/bergman/my2024/X/oh-my-project/.porjectvenv/bin/python -m autopep8 -
2025-09-05 11:04:38.048 [info] CWD Server: /Users/bergman/my2024/X/oh-my-project/技术/脑图_keydog_贱狗/code
- 2025-09-05 11:04:38.048 [info] /Users/bergman/my2024/X/oh-my-project/.porjectvenv/bin/python -m autopep8 -
配置文件3种形式, 表现不同:
ignore = ["W293", "W503", "W504", "C0303", "C2401"] # indent_size2生效
ignore = W293,W503,W504, C0303, C2401 # indent_size2不生效,实际会格式化为4
ignore = "W293,W503,W504, C0303, C2401" # indent_size2生效
结论:
- 非常悲催, autopep8也是不支持空行缩进的, pythonpep有病.
- 累了, 就这样吧, isort+autopep8, 就这样吧.
后记 2025-9-26
如何判断当前使用的是哪一个格式化器?
- 文本编辑窗口中, 用鼠标右键点击打开的python文本, 选择 format document with, 此时就能看到默认格式化器了.
配置
- 其实可以都写在pyproject.toml
[tool.black]
exclude = '''
/(
\.git
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| _build
| buck-out
| build
| dist
)/
'''
include = '\.pyi?$'
line-length = 120
[tool.isort]
line_length = 999 # 同一行长
multi_line_output = 0 # 0 = 单行模式
profile = "black" # 与 Black 对齐风格
# 关键:保留空行里的空格
ensure_newline_before_comments = false
remove_redundant_aliases = false
# 5.x 新选项
treat_all_comments_as_code = true
[tool.autopep8]
hang_closing = false
ignore = 'w293' # "W293,W503,W504,C0303,C2401" # 不想修的 PEP 8 错误码
indent_blank_lines = true
indent_size = 2
max_line_length = 999
#E133,E226,E302,E305,E704,W503,W504
# 关键:给空行也插入缩进空格(需要 autopep8 ≥ 2.0)
- 我的yapf写在了: .style.yapf
[style]
based_on_style = pep8
column_limit = 999
split_penalty_after_opening_bracket = 7000
split_penalty_for_added_line_split = 7000
# split_penalty_excess_character = 7000
split_penalty_import_names = 0
# 合并多行
join_multiple_lines = true
# 参数拆分为多行
allow_multiline_lambdas = false
# 右括号对齐
dedent_closing_brackets = true
# 参数前换行
split_before_named_assigns = false
# 复杂推导式换行
split_complex_comprehension = false
# 字典换行
each_dict_entry_on_separate_line = false
# Import语句相关设置
coalesce_brackets = true
force_multiline_dict = false
allow_split_before_dict_value = false
# 禁止删除“行尾/空行”空格
trim_whitespace_in_blank_lines = false