资讯动态

Python代码质量守护者:Pylint与Flake8组合使用实战

发布时间:2026/10/14 19:40:28 来源:尧图企业网站定制
1. 从能跑到能维护为什么我开始较真代码质量代码写多了之后我慢慢意识到一个问题一段代码能跑起来和一段代码是健康的完全是两回事。刚入行那会儿我也觉得能出结果就是好代码后来被项目里那些几百行没人敢动的函数、莫名其妙冒出来的全局变量、以及改了 A 文件结果 B 文件跟着崩的诡异经历反复教育之后我才真正开始认真对待代码质量这回事。而这场转变的起点就是我在这篇文章标题里写下的这两个工具Pylint 和 Flake8。很多刚开始接触工程化开发的朋友可能对这两个名字既熟悉又陌生。熟悉是因为不管在哪份技术文档、哪篇工程规范里似乎都能看到它们的身影陌生是因为大多数人刚开始的感受都是这东西好烦动不动就报一堆警告甚至标红错误。但我想说如果你真的把它们用明白了这两个工具完全可以成为你项目里最靠谱的代码质量卫士。它们能帮你把肉眼容易漏掉的问题在提交之前就揪出来能统一团队的编码风格还能逼着你在写代码的时候多想一步为什么。这篇文章我会从实际使用的角度出发把 Pylint 和 Flake8 怎么选、怎么配置、怎么集成到日常开发流程里、以及我在实际项目中踩过的坑和总结出来的经验都整理出来。不管你是刚接触 Python 工程化的新手还是已经写了一段时间但一直被工具链配置困扰的老手这篇文章应该都能给你一些能直接落地参考的东西。2. 先搞清楚它们到底是什么Pylint 和 Flake8 的关系既然要聊这两个工具我觉得有必要先把它们各自是什么、解决的问题是什么、以及它们之间的重叠和差异讲清楚。不然很多人容易陷入一个误区以为装了其中一个就万事大吉或者两个都装了却不知道各自该信谁的输出。2.1 Pylint规则最全、最挑剔的静态分析器Pylint 是一个老牌的 Python 静态代码分析工具。它的历史可以追溯到十几年前核心目标是对 Python 代码做非常全面的检查覆盖面横跨代码风格、潜在错误、设计问题、重复代码、重构提示等多个维度。说得更直白一点Pylint 就像是一个特别严格、特别较真的 code reviewer。它不满足于只在语法层面对代码把一把关还会通过分析代码的抽象语法树去判断你的代码是不是有坏味道。比如你写了个函数但函数里面定义了却没用到的变量Pylint 会告诉你你的类里少了init方法它也可能给你提示你的模块开头没有 docstring它也要说两句。甚至你定义了某个方法却从没被调用过它都会在执行分析之后给你列出来。Pylint 的检查项数量极其庞大光是比较常见的编码规范检查规则就覆盖了命名风格、导入顺序、异常处理、控制流分析、类型检查等多个类别。它最终会给出一个十分制的评分这也是很多人第一次用 Pylint 的时候最容易受到冲击的地方——自己辛辛苦苦写出来的代码居然只能拿 3 分、5 分甚至更难看。2.2 Flake8轻量、快速、聚焦风格与常见错误Flake8 则是另一条路线。它本质上是把几个工具打包在一起使用PyFlakes 负责检查逻辑错误pycodestyle 负责检查代码风格是否符合 PEP 8而 McCabe 负责检查代码的圈复杂度。这三个部分组合起来就是 Flake8 的全部能力。认真说了你可能不信Flake8 的速度远比 Pylint 快。因为它本质上做的是一种基于语法树和简单模式匹配的检查不涉及特别深的类型推断或数据流分析。这就意味着哪怕你的代码有几万行跑一次 Flake8 也就是几秒钟的事情非常适合在本地提交代码之前或者 CI 流程里频繁执行。Flake8 的检查重点也更偏向风格统一和低级错误。比如行尾多了空格、缩进不对、引号使用不一致、函数名不符合蛇形命名规范、定义了的变量没被使用、直接 import 进来的模块没有派上用场等等。这些错误虽然不一定会直接导致程序崩溃但确实会在项目变大之后变成阅读和维护的障碍。2.3 两者的重叠、差异与互补关系很多人会问那我到底该选 Pylint 还是 Flake8我的答案是如果你是一个人在维护小项目选哪个都行但如果你在正经的工程化团队里成年人其实不做选择两个都用才能发挥最大价值。我们稍微用一个表格来对比它们在实际使用中最明显的区别对比维度PylintFlake8检查范围风格、错误、设计、重构、重复代码风格、常见错误、圈复杂度分析深度较深含数据流与控制流分析较浅偏语法树级分析执行速度较慢大型项目可能需要数秒至数十秒极快几万行代码秒级完成误报率偏高需要配置和过滤相对较低误报少输出形式详尽的报告和评分简洁的问题列表配置灵活度高规则可细粒度控制中等配置相对简单适合场景提交前深层次检查、Code Review 辅助快速检查、CI 阶段门禁、风格统一从这张表可以看出来Pylint 适合做定期体检Flake8 适合做日常安检。日常开发里每次提交代码之前用 Flake8 快速过滤一遍低级错误成本很低、效率很高到了准备合并分支或者发布版本的时候再用 Pylint 做一轮深度检查把那些更隐蔽的设计和逻辑隐患揪出来。两者组合使用才是比较完整的质量保障方案。3. 动手安装与入门先让工具跑起来聊完原理和差异我们直接进入实操环节。先别急着研究复杂的配置文件我建议你先把这两个工具装好在随便一个 Python 项目里跑一把感受一下它们的脾气到底是什么样的然后再谈配置和集成。3.1 安装方式pip 一把梭安装本身没什么难度在虚拟环境里执行两条命令即可。因为你日常很可能已经用虚拟环境隔离依赖了我强烈建议把 Pylint 和 Flake8 装进项目的虚拟环境里而不是全局环境这样不同项目的配置和版本可以互不干扰。pip install pylint pip install flake8装完之后你可以顺手看一下版本pylint --version flake8 --version你要是想把它们固定在某个已知稳定的版本上用 pip freeze 找到当前版本号然后通过 requirements 文件锁定版本即可。3.2 入门实测用一个小例子感受两者的输出空谈理论没意思。我们写一段故意包含问题的 Python 代码看看这两个工具分别会报出什么。下面这段代码模拟了一个很典型的匆忙交付场景里面虽然逻辑能跑但问题不少import os import sys import requests def FetchData(url): data requests.get(url) res data.json() return res[data] def process(url, flag): result FetchData(url) if flag True: print(result) return result这段代码的问题不少模块 os 和 sys 导入之后没用、函数命名用了驼峰而不是蛇形、变量名 res 含义不明、flag True 这种比较方式不够 Pythonic、函数之间缺少空行、import 顺序也没有符合规范。分别执行flake8 demo.py pylint demo.pyFlake8 的输出大致是这样的demo.py:1:1: F401 os imported but unused demo.py:2:1: F401 sys imported but unused demo.py:3:1: I100 Import statements are in the wrong order demo.py:5:1: E302 expected 2 blank lines, found 1 demo.py:5:5: N802 function name should be lowercase demo.py:11:13: E712 comparison to True should be if flag is True: or if flag:Pylint 的输出则要啰嗦不少除了上面类似的风格问题之外还会给出关于 missing-docstring、invalid-name、unused-import、simplifiable-if-expression 之类的提示并且最后会给出一个总体评分。如果你没有配置过 Pylint那么第一次跑出来的那个分数大概率不会好看。这一步其实不是让你追求零报错而是让你直观地建立一种概念这些工具能看到的往往比我靠眼睛扫代码看到的要细得多。4. 实战中如何配置 Pylint从被它气死到为我所用Pylint 功能强大但默认规则确实过于严格这也是很多人用了一两次就把它丢到一边的原因。其实只要把配置文件调好Pylint 完全可以变成一把趁手的兵器而不是一个只会挑剔你的杠精。4.1 生成基础配置文件在项目根目录执行pylint --generate-rcfile .pylintrc这时候你会得到一个几百行的配置文件。不要被它的体量吓到你日常真正需要改的地方其实也就集中在少数几个小节里。生成这个文件的目的是为了有一个完整的参照当你需要调整某个规则时能快速找到对应的配置位置。需要提醒的是老版本和新版本的 Pylint 生成的配置文件结构会有细微差异如果你的项目横跨了多个 Python 版本建议在项目里锁定的 Pylint 版本下生成配置避免配置项不兼容的问题。4.2 核心配置项解析不要全盘接受也不要全盘禁用Pylint 配置里面最常用的几个小节分别是 MASTER、MESSAGES CONTROL、BASIC、DESIGN 和 REFACTOR。我一个个说重点。MASTER 小节里你能控制比如 jobs 参数用来让 Pylint 多进程运行对大项目能明显提升执行速度。默认值是 1如果你的机器配置还行改成 4 或者 8 都可以。另外 ignoring-paths 和 ignore-patterns 能让你跳过某些文件或目录比如 migrations、build、dist 这些都不需要被静态检查。MESSAGES CONTROL 小节是很多人的主要调整区域。你可以用 enable 和 disable 分别控制需要额外开启或屏蔽的检查项。比如说 disablemissing-function-docstring就能关掉函数必须有 docstring这种对内部函数过于严苛的要求同时保留对公共接口模块的注释要求。BASIC 小节主要管命名风格。比如你可以设置 const-rgx、class-rgx、function-rgx 等参数来定义各种类型名字的合法正则。如果你不想把太多精力花在和命名规范较劲上可以直接把 default-rgx 改成更宽松的表达式或者干脆用 disableinvalid-name 关掉命名检查。但我不建议全关因为命名风格某种程度上也是代码可读性的保障适当地保留一些约束对长期维护是利大于弊的。DESIGN 小节里最重要的是 max-args 和 max-locals分别限制函数的最大参数个数和最大局部变量数。默认值分别是 5 和 15。我在实际项目中一般会把 max-args 适当放宽到 8 左右毕竟有些历史代码或特定业务场景就是需要更多参数一棍子打死容易引发团队抵触情绪。REFACTOR 小节则包含 max-returns 和 max-branches 等主要用于提示函数是否太过复杂、分支太多。这里我建议保留默认值或者稍微收紧因为过深的嵌套本身确实值得警惕。4.3 我的实际配置经验一线项目调参参考我直接把一份我实际项目里用过的、经过团队反馈调整后的配置核心片段分享出来你可以在此基础上根据自己项目的情况再改[MASTER] jobs4 ignoreCVS ignoring-pathsbuild,dist,venv,.venv,tests/mock [BASIC] # 允许短名称如 i, j, k, e 等作为局部变量 const-rgx(([A-Z_][A-Z0-9_]*)|(__.*__)|(^[a-z_][a-z0-9_]*$)) function-rgx(([a-z_][a-z0-9_]*)|([a-z_][a-z0-9_]*)) [MESSAGES CONTROL] # 屏蔽对内部函数 docstring 的强制要求 disablemissing-function-docstring, missing-module-docstring, fixme, too-many-locals, too-many-arguments [DESIGN] max-args8 max-locals20 max-branches15 [REFACTOR] max-returns8 max-branches12顺带补充一下有些团队会用 isort 来统一 import 顺序配合 Pylint 的 import 检查一起用。Pylint 的 wrong-import-order 和 ungrouped-imports 可能会和 isort 的排列有一些重叠和冲突实际用的时候可以在 Pylint 里把这两类规则关掉专心交给 isort 去管这样职责更清晰。5. Flake8 的配置与使用技巧轻量工具也有大学问很多人觉得 Flake8 配置简单于是就直接用默认配置这其实浪费了它的很多价值。Flake8 虽然轻量但配置合理与否直接决定了它在你的项目里是真卫士还是背景板。5.1 用 setup.cfg 管理 Flake8 配置Flake8 的配置可以放在项目根目录的多个位置我习惯用 setup.cfg 统一管理因为它本身就是一个通用的 Python 项目配置文件可以同时承载其他工具的配置整个项目根目录不会到处都是配置文件整洁很多。在 setup.cfg 里新增如下片段[flake8] max-line-length 120 max-complexity 15 exclude .git,__pycache__,build,dist,venv,.venv,node_modules,migrations extend-ignore # E203 是黑名单里先挑出来的它和 PEP8 的冒号后一致 E203, # W503 换行发生在二元运算符之前 W503, # 允许某些历史遗留代码里出现的行尾空格 W291max-line-length 我建议设置为 120虽然 PEP 8 的官方建议是 79但说实话在现在的宽屏编辑器时代79 的限制对很多项目来说反而降低了可读性会因为不断换行打断思路。120 是我在多个项目里验证过比较舒服的阈值。max-complexity 是 McCabe 圈复杂度的上限默认没有限制这一点必须小心。如果你不设置这个值那 Flake8 就不会真正提示你函数过于复杂的问题而圈复杂度往往是代码可维护性的一个非常硬的指标。我见过不少面条式函数几百行代码嵌套好几层 if 和 for循环和分支搅在一起这种函数哪怕注释写得再漂亮读起来也是灾难。所以这里一定要给出一个值我常规推荐 10 到 15可以根据你的项目情况适当调整。5.2 Flake8 常见错误码速查熟悉 Flake8 的错误码能让你在看到输出的时候不用每次都去查文档。我整理了一份高频错误码速查表错误码含义典型场景E101缩进使用了混用空格和制表符复制粘贴其他编辑器代码时E201括号内有多余空格函数调用时foo( x )E231逗号、冒号后缺少空格字典、列表定义时格式化不统一E302类或函数上空行数量不对顶级定义之间缺少两个空行E501行长度超过 max-line-length长字符串、长函数调用E712与 True/False 的比较方式不标准if flag TrueE731lambda 赋值给变量f lambda x: x 1F401模块被导入但未使用残留 importF841局部变量被赋值但未使用调试时留下的临时变量C901函数圈复杂度超过阈值嵌套过深、分支过多的函数这份表可以打印出来贴到工位旁边。如果你在做 Code Review看到这些错误码在自己的项目里高频出现其实也就说明团队里有些共性的编码习惯需要统一了。5.3 结合 pre-commit 实现提交前自动检查Flake8 如果只在 CI 里跑往往会有一个延迟效果代码提交到远端之后才发现问题这时候开发者的心态已经切换到下一件事了让他回头修代码很痛苦甚至会产生抵触情绪。比较好的做法是把 Flake8以及可选地 Pylint集成到本地提交之前的环节让问题在源头就被拦截。我推荐用 pre-commit 框架来管理 git 的 pre-commit 钩子。在项目根目录创建 .pre-commit-config.yamlrepos: - repo: https://github.com/PyCQA/flake8 rev: 7.0.0 hooks: - id: flake8 args: [--configsetup.cfg] - repo: https://github.com/PyCQA/pylint rev: v3.2.0 hooks: - id: pylint args: [--rcfile.pylintrc, --disableimport-error, --jobs4]安装好之后跑一次 pre-commit install。从这以后每次 git commit 的时候Git 都会先跑一遍 Flake8有严重错误就直接拒绝提交。你可以设置让 Pylint 只输出 warning 级别以上的信息降低由于规则过严导致的提交阻塞。有一点要注意pre-commit 钩子在每个环境里都需要装一次依赖团队里来了新成员 clone 项目之后需要执行pre-commit install才能生效。所以最好在项目的 README 里写清楚这一步骤不然钩子形同虚设。6. 把工具接入 CI让质量门禁成为团队共识工具只在本地跑永远只能管住个人自己。要让整个团队都能稳定地产出质量差不多的代码必须把检查流程接入持续集成环境。不管你是用哪种 CI 平台核心思路都一样在跑测试之前或者之后增加一个单独的静态检查阶段一旦检查失败就直接让流水线挂掉。6.1 一个极简的 CI 检查流程设计假设你已经有一个基于 Python 的项目CI 流水线大概可以拆成下面几个阶段stages: - lint - test lint: stage: lint script: - pip install flake8 pylint - flake8 --configsetup.cfg . - pylint --rcfile.pylintrc mypackage/ rules: - if: $CI_MERGE_REQUEST_IID # 在合并请求时运行这里有一个细节值得展开Flake8 检查时可以直接对整个仓库跑因为它速度足够快即时代码量很大也不会太耗时。但 Pylint 就应该慎重选择检查范围通常是针对你真正需要维护的包目录或者源码目录而不是全仓库。因为 Pylint 跑全仓库既慢还容易因为测试代码、迁移脚本等不属于核心业务逻辑的文件产生大量无用噪音反而让真正值得关注的问题淹没在警告堆里。6.2 设定质量门槛分数与错误数量的博弈很多团队在 CI 里加了 Pylint 之后会遇到一个很现实的问题老项目历史遗留代码太多一开始跑 Pylint 就是几千个 warning如果直接把门槛设成零错误那么 CI 永远红着开发节奏被拖累最后大家会直接绕过规则甚至放弃这个门禁。我踩过这个坑。后来总结出来的可行思路是渐进式收紧第一阶段先设置一个可以接受的 Pylint 最低分比如 7.0 分低于这个分数就挂掉流水线同时配合使用 Pylint 的持久化报告每次只处理增量问题。等团队的代码质量整体上来了再慢慢把阈值提高到 8.0、9.0 甚至更高。Flake8 那边则更简单因为它没有分数概念只有错误和警告。建议把严重错误比如 F 开头的 PyFlakes 错误直接作为硬性阻断条件而纯风格的提示可以先只做提示不阻断。等团队适应之后再逐步调整为严格模式。6.3 区分错误等级做精细化处理Pylint 的输出信息带有不同的类别标记常见的有C (convention) 风格问题比如命名、docstring 缺失。R (refactor) 重构建议比如函数太复杂、有重复代码。W (warning) 潜在风险比如可能误用的语法或可疑操作。E (error) 确定的错误比如访问了不存在的变量或导入了不存在的模块。F (fatal) 导致分析失败的致命问题。我的建议是在 CI 的 Pylint 命令后面顺手加一个--fail-under8参数同时配合 enable 和 disable 配置确保只有 E 级和 F 级的错误能直接导致流水线失败而 C 类和 R 类先以提示为主。等到团队的整改节奏跑起来之后再把权重逐步提高。这样既保证了质量门禁不沦为摆设又不会因为规则严到不近人情而引发团队逆反心理。7. 实战中打通 Pylint 与 Flake8 的协作流前面已经讲了它们各自怎么用这一节我想专门聊聊二者怎么配合使用、如何避免它们之间的冲突以及我在一线项目里摸索出来的协作流程。7.1 让两个工具各司其职避免重复劳动从实际效果上看Flake8 适合挡在门口Pylint 适合守在深水区。每次开发者写代码的过程中可以在编辑器里配置保存时自动跑 Flake8这样低级错误在敲代码的同时就能被看到等到准备提 Pull Request 之前再手动跑一次 Pylint检查更深层的代码设计问题。我推荐在 IDE 里配置保存时运行 Flake8但不建议保存时运行 Pylint因为 Pylint 在某些大文件上可能要跑好几秒频率太高会干扰心流。写代码的时候让 Flake8 在旁边保持安静但随时待命Pylint 留到有阶段性成果之后再检查这是我认为在流畅性和完整性之间比较平衡的组合方式。7.2 建立一份团队质量例外清单没有任何一个项目能在所有规则上都做到完美。有些规则在特定业务场景下确实应该被豁免比如某些核心算法模块可能需要很长的参数列表、某个历史遗留模块的命名已经与外部系统耦合而无法随意重构。这时候与其让工具每天重复报错不如主动维护一份质量例外清单。我一般会在仓库里建一个 docs/code-quality-exceptions.md记录每条被豁免的规则、豁免的文件、豁免的原因以及下次复审的时间。然后在 .pylintrc 和 setup.cfg 里利用文件级别的 disable 指令或者 per-file-ignores 功能来精确豁免而不是一刀切全局关闭。例如 Flake8 的 per-file-ignores[flake8] max-line-length 120 per-file-ignores tests/*: E501,W291 old_module/*: F401,W0611这样既保证了核心代码区质量严格也给了迁移期代码一定的缓冲空间。不过我会在例外清单里给每一项都写上截止日期避免例外变成常态。7.3 一个轻量级报告脚本让检查结果可视化团队协作的时候纯命令行输出是不够直观的。因为我发现很多团队成员看到满屏的 Pylint 输出时根本不知道从何下手容易产生畏难心理。后来我写了一个简单的汇总脚本把 Flake8 和 Pylint 的输出做轻量级解析按严重程度排序输出摘要并且给出一条问题最集中的文件 Top 10 排行。import subprocess import sys from collections import Counter FILES [mypackage/] flake8_output subprocess.run( [flake8, --configsetup.cfg, .], capture_outputTrue, textTrue ).stdout pylint_output subprocess.run( [pylint, --rcfile.pylintrc] FILES, capture_outputTrue, textTrue ).stdout counter Counter() for line in flake8_output.splitlines(): if line.strip(): parts line.split(:) file_name parts[0] code parts[3].split()[0] counter[(file_name, code)] 1 for line in pylint_output.splitlines(): if : in line and line.split(:)[-1].strip(): # 简单解析 Pylint 的告警行 parts line.split(:) file_name parts[0] code parts[3].strip().split(()[0] counter[(file_name, code)] 1 for (file_name, code), count in counter.most_common(15): print(f{count:5d} {code:8s} {file_name})这个脚本的目的不是替代官方的 HTML 报告输出而是给团队一个非常快、非常直观的全局视图哪几个文件问题最集中、哪几类错误最高发一目了然。有了这个数据安排重构优先级的时候就不用拍脑袋了。8. 踩过的坑与排查经验实录最后这部分我想集中聊聊我在实际落地这两个工具的过程中遇到过的比较典型的问题和排查思路。哪怕你暂时还没遇到先知道这些坑在哪里后面也能少走弯路。8.1 同一条规则反复报但查了配置明明屏蔽了这类问题出现的原因八成是因为配置文件没起作用。常见情况有三种一是 Pylint 或 Flake8 在运行的时候没有按照预期的路径去读取配置文件。比如你在 A 目录下运行 flake8但配置文件在 B 目录如果你没有显式指定 --config 参数工具只会向上查找默认的几个文件名和路径。二是你的 IDE 集成了工具但 IDE 用的配置文件路径和你在终端里用的不一样导致两者结果不一致。三是有的人会在几个配置文件里重复设置规则然后在某个文件里 enable 了一次又在另一个文件里 disable 了一次最终结果取决于工具到底按哪个配置为准而你自己却已经记不清了。排查这个问题的思路其实很直接先用 --version 确认工具版本然后运行工具的时候加上显示配置项的参数或者干脆先在项目根目录下、用绝对路径显式指定一次配置文件排除路径因素。把配置来源确认清楚了绝大多数配置不生效的困惑都能解开。8.2 Flake8 和 Pylint 报同样的错到底听谁的实际项目里经常遇到同一段代码Flake8 报一个错误码Pylint 报另一个错误码但描述的其实是同一个问题。例如对于未使用的导入Flake8 报 F401Pylint 报 unused-import。这种情况我通常的做法是以 Flake8 的结果为准来快速过滤低级问题因为它更简单直接、速度更快。以 Pylint 的结果为准来检查设计层面的问题因为它检查更全面。当两条规则冲突的时候比如 Flake8 提示某个 lambda 应该改成普通函数而 Pylint 提示某个函数应该拆分成 lambda就建议以团队编码规范为准统一在例外清单里记录下来。工具是服务于代码质量目标的不是反过来被工具绑架。8.3 从满屏红线到心平气和的落地建议很多人第一次在完整项目里运行 Pylint 时看到满屏 warning 的心态是崩溃的。这里我分享一个我自己的经验不要期待一夜之间把历史债务清零。你要做的第一件事是先把你最近接手或正在开发的模块的检查结果整改到可接受状态然后把新代码的检查门槛拉满旧的代码排期慢慢改。这样团队成员不需要在每次提交代码的时候都要面对一大堆和陈年旧账有关的问题工具的使用阻力会小很多。另外我强烈建议在团队里设置一个质量守护者的轮岗机制每周由一个人负责 review 最新的 lint 报告推动重点问题修复。这个角色不一定需要很资深的工程师来当因为 lint 报告本身就是一种客观的数据输入给到团队之后大家基于数据讨论优先级比单纯口头约定注意代码质量要实在得多。8.4 一份实操速查表我整理了一个实际排查过程中经常用到的速查表覆盖工具行为确认和常见修复方案现象可能原因排查与处理办法Flake8 不读 setup.cfg 配置配置文件位置不对或权限问题用flake8 --configsetup.cfg .显式指定Pylint 提示unable to import项目的 sys.path 未包含源码目录设置[MASTER] init-hook添加路径两个工具对同一行报不同错误码工具检查理念不同以团队规范为准记录例外CI 里 Pylint 分数不稳定未锁定 Pylint 版本在 requirements 中锁定版本或使用约束文件pre-commit 钩子不生效未执行 install 或钩子被跳过执行pre-commit install检查 git 状态Pylint 检查速度太慢文件太多、jobs1使用--jobs4提升并行度Flake8 误报某些代码风格规则和项目风格不一致在 extend-ignore 中显式声明豁免关于init-hook的问题我补充一句。如果你遇到 Pylint 无法导入某个自定义模块的情况常见解法是在配置里加[MASTER] init-hookimport sys; sys.path.append({project_home})这本质上是告诉 Pylint在开始分析之前先把这个路径加进模块搜索路径里。这种方式比到处加 sys.path 垃圾代码要干净得多。9. 我的一些使用习惯和最后的经验分享写到这里主体内容其实已经讲得比较充分了。最后这段我不打算做什么总结只想分享一下我自己在实际使用过程中沉淀下来的几个习惯也许能给你一点参照。我一般每天开工第一件事先把负责的模块跑一遍 Flake8看到输出基本为零或者只有个位数的问题心情会比较稳定如果输出一堆就先处理掉再开始写新代码。这样能避免带着旧债务去写新代码让新债和旧债混在一起最后根本分不清哪些是这次改的。这个习惯成本极低但长期坚持下来对保持代码库整洁的帮助非常大。Pylint 我不会天天跑通常是在完成一个功能或者准备提交合并请求之前跑一次。跑之前会先看一眼配置里的 disable 列表有时候因为临时调试加了一些宽松配置跑完会记得改回来。这里也有一个小技巧Pylint 支持在代码里用注释按行屏蔽规则比如# pylint: disableunused-argument但我不建议到处用因为屏蔽写多了代码里全是免检标记工具也就形同虚设了。能用配置文件解决的问题就不要用行内注释。还有一个我特别想强调的点工具是死的标准是活的。Pylint 和 Flake8 给你的那些告警本质上不是你错了而是这一段代码在长期维护视角下有优化空间。刚开始被它们挑剔的时候难免觉得烦但当我真正经历过半年后重新打开自己写的模块两分钟就能看懂当时的设计意图那种顺畅感之后我就彻底接受了这些工具的脾气。你把它们当成两个性格不同的同事就行Flake8 是那个见不得桌子乱的急性子Pylint 是那个喜欢翻你草稿纸问这里为什么这么写的细节控。有这两个同事在工位旁盯着你的代码只会越写越稳。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑