vscode的python格式化让人大吃一惊, 摸不着头脑.

明显的坑
  1. 截止今天, 你在vscode的setting里面直接搜索defaultFormatter, 他给你显示的是none, 然后, 你切换为文本json格式, 再搜索, 欧豁…能搜出来4个.
  2. 如果你是pip安装, 然后vscode之中是否执行以及如何执行就非常复杂.
    1. 某些时候会被直接执行, 取决于vscode的版本, 时不时就抽风随机执行一个你安装个格式化器.
    2. 某些时候如果vscode没找到setting对应的插件, 他会到路径里面找对应的格式化器.
  3. 格式化器有各种执行的可能性
    1. 插件执行, 这个最稳, 如果装了插件一定执行
    2. 路径执行/pip安装执行, 这两个不一定
    3. git的各种环节执行
    4. 全局格式化器, 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

配置文件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, 此时就能看到默认格式化器了.

配置

  1. 其实可以都写在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)

  1. 我的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