码农高天审查开源代码 批位运算滥用与反射测试过度设计

【Code Review】把&当and用可是不行!测试写成这样也有点离谱哦! — 码农高天

码农高天

以位运算符替代逻辑与并借反射函数名执行测试不仅严重破坏语义与可读性,更将原本三行循环即可完成的断言膨胀为数十行冗余样板。

AI-assisted summary of 【Code Review】把&当and用可是不行!测试写成这样也有点离谱哦! — original source. Check the original for full context.

Source published:

Key ideas

  • 在开源与正式项目中,不建议将包含本地配置的 .vscode 文件夹纳入版本控制提交到代码仓库。 (0:00)
  • Python 逻辑判断中切勿用按位与运算符 & 代替 and,即便运行结果偶然一致也会破坏代码语义并误导读者。 (5:00)
  • 测试用例将数据抽离到字典后,手写几十个 test_n 函数并用反射获取自身名称反查执行是毫无必要的过度设计,应直接循环遍历断言。 (10:00)

Detailed notes

## Background 该视频由 YouTube 频道“码农高天”于 2024 年 2 月 5 日发布。视频简介说明这是 Code Review 系列改版后的新期内容,旨在通过审查粉丝编写的时间处理工具 date_range_prefix,指出可以进一步优化与提升代码水平的地方。

## TL;DR 本期视频对粉丝编写的日期前缀生成工具进行了系统性代码审阅。高天首先指出了项目管理与接口设计的不足,包括不应在仓库中提交 .vscode 私有配置、单字母变量命名易混淆,以及输入输出日期分隔符不一致的问题。接着重点批评了在 Python 中错误使用按位与运算符 & 代替逻辑运算符 and、深层分支缺乏行内注释和封装度不足等可读性坏味道。最后剖析了测试文件中用反射获取函数名、反查字典并机械重复几十个测试用例的“离谱”设计,演示了如何用简单的循环重构大幅精简测试代码。

## Atmosphere & style 整体节奏轻快且信息密度极高,告别了过往直播的漫长拖沓,直奔代码痛点。高天的讲解既保持了资深程序员的技术敏锐度,又带着亲切幽默的吐槽风格,尤其在面对用黑科技反射反查测试用例的奇葩写法时展现出哭笑不得的真实反应。整场审阅兼顾工程严谨性与趣味性,让观众在会心一笑中直观体会到代码语义与规范的重要性。

## Bulletin - [00:00](https://www.youtube.com/watch?v=ERosfjjY40Y&t=0s) 在开源与正式项目中,不建议将包含本地配置的 .vscode 文件夹纳入版本控制提交到代码仓库。 - [05:00](https://www.youtube.com/watch?v=ERosfjjY40Y&t=300s) Python 逻辑判断中切勿用按位与运算符 & 代替 and,即便运行结果偶然一致也会破坏代码语义并误导读者。 - [10:00](https://www.youtube.com/watch?v=ERosfjjY40Y&t=600s) 测试用例将数据抽离到字典后,手写几十个 test_n 函数并用反射获取自身名称反查执行是毫无必要的过度设计,应直接循环遍历断言。

## Key takeaways - [00:00](https://www.youtube.com/watch?v=ERosfjjY40Y&t=0s) 编辑器私有配置(如 .vscode 文件夹)不应上传至版本控制,应保持公共仓库干净整洁。 - [00:00](https://www.youtube.com/watch?v=ERosfjjY40Y&t=0s) Docstring 中的示例排序应具备递进逻辑,建议从基础场景(按天/整月)过渡到大粒度(整年)再到缺省参数展示。 - [00:00](https://www.youtube.com/watch?v=ERosfjjY40Y&t=0s) 避免使用 s、e 等单字母变量名混淆起止,也不建议直接覆盖原变量名引起类型变化,推荐使用 start_dt 等具名变量。 - [00:00](https://www.youtube.com/watch?v=ERosfjjY40Y&t=0s) 避免无意义或易引起歧义的缩写,如将结果列表命名为 rng 极易被误读为随机数生成器(Random Number Generator)。 - [05:00](https://www.youtube.com/watch?v=ERosfjjY40Y&t=300s) 严禁在 Python 条件判断中滥用 & 代替 and,保留清晰明确的布尔逻辑语义并减少不必要的括号嵌套。 - [05:00](https://www.youtube.com/watch?v=ERosfjjY40Y&t=300s) 第三方库返回元组切片缺乏可读性时(如 calendar.monthrange(...)[1]),应封装为具名辅助函数(如 month_end_date)。 - [05:00](https://www.youtube.com/watch?v=ERosfjjY40Y&t=300s) 将长生成逻辑拆出 range 赋予临时变量 days 能够有效避免长单行代码破坏可读性。 - [05:00](https://www.youtube.com/watch?v=ERosfjjY40Y&t=300s) 长逻辑分支与深层嵌套应补充行内注释,避免读者在相隔数十行的 if-else 之间来回翻找上下文。 - [05:00](https://www.youtube.com/watch?v=ERosfjjY40Y&t=300s) 警惕分支下的恒成立条件判断,当下游生成器已自带边界处理(如空列表)时应精简冗余判断。 - [10:00](https://www.youtube.com/watch?v=ERosfjjY40Y&t=600s) API 接口设计应保持输入与输出格式的一致性或兼容性,避免输入短横线却只输出斜杠带来的认知负担。 - [10:00](https://www.youtube.com/watch?v=ERosfjjY40Y&t=600s) 基于表格驱动测试时,切忌使用反射获取当前函数名反查字典的黑魔法,简单清晰的循环断言才是更优解法。

## Detailed walkthrough ### [00:00](https://www.youtube.com/watch?v=ERosfjjY40Y&t=0s) 仓库结构、函数设计与参数规范

Code Review 系列正式改版回归,由以往的直播形式改为节奏更快、信噪比更高的视频录制方式,并在知识星球中提供报名和要点总结。本次 Review 的项目是粉丝编写的小工具 `date_range_prefix`,目标非常清晰:根据输入的起止日期生成一个前缀日期列表。

在仓库的根目录中,作者上传了核心 Python 源码、测试文件、LICENSE、README、`.gitignore`,以及一个包含本地测试配置的 `.vscode` 文件夹。针对 `.vscode` 目录的提交,高天给出了明确的工程规范建议:“在这里我个人是强烈建议不要上传这个东西的……一般来说我们建立 repo 是不太会把这个.vscode 文件夹传上来的。”虽然个人在多台机器间同步配置尚可理解,但在正规或较大型的开源项目中,不应将编辑器私有配置纳入版本控制。

```mermaid flowchart LR accTitle: date_range_prefix 核心逻辑流程 accDescr: 展示函数从参数解析、单位判断到格式化输出的整个处理分支

subgraph Input["输入解析"] A["输入 start & end"] --> B{"参数校验 & 默认值"} B --> C["转换为 datetime (S & E)"] end

subgraph Logic["区间粒度判断"] C --> D{"同一年?"} D -->|"是"| E{"同一月?"} D -->|"否"| F["跨年处理:掐头去尾 + 整年补全"] E -->|"是"| G["整月/按天展开"] E -->|"否"| H["跨月处理:首尾月 + 递归补全"] end

subgraph Output["结果聚合"] G --> Out["返回 RNG 日期列表"] H --> Out F --> Out end ```

进入代码正文,函数实现了一段 docstring,但英文说明读起来并不容易理解。好在作者提供了详尽的调用示例(例如输入 `2023-01-30` 到 `2023-03-01`,输出 `['01/30', '01/31', '02', '03/01']`),直观展示了函数的核心逻辑——以天为基础粒度表达时间段,遇到整月或整年时进行聚合折叠。然而,示例中已经暴露了格式不一致的疏漏(原本应为斜杠却写成了横杠)。针对函数开头的默认参数与变量命名,高天指出了几个需要重构的点:

- **示例排序改进**:建议先展示“按天/整月”,接着是“整年”,最后放“缺省参数(默认当天)”,层层递进更易阅读。 - **默认参数处理**:未提供 `start` 时默认为 `today`,未提供 `end` 时默认为 `start`,判断逻辑使用了 `is None`,写法规范。 - **避免单字母变量名**:代码将字符串转为 datetime 对象后命名为 `s` 与 `e`。应避免使用单字母命名,以防后续读代码时混淆起止;同时也不建议直接覆盖原变量名引起类型变化,推荐使用 `start_dt` 这种具名变量。 - **避免无意义的缩写**:返回值列表被命名为 `rng`,极易被误读为随机数生成器(Random Number Generator)。在不需要极度压缩长度的地方应写清楚,例如直接使用 `date_range` 或 `result`。

---

[05:00](https://www.youtube.com/watch?v=ERosfjjY40Y&t=300s) 位运算符误用、封装与代码可读性问题

在核心分支逻辑中,代码根据是否同一年、同一月分别进入不同处理路径。当起止日期在同一月且刚好覆盖整月时,代码出现了一个典型的 Python 语法与语义误区——使用按位与运算符 `&` 代替逻辑运算符 `and`。

高天强调了语义在编程中的核心地位:“大家千万不要在 Python 里用这个 `&` 符号来代替 `and`,这是非常错误的一种写法啊。我很多次跟大家强调语义是有意义的,就哪怕你运行的结果是没错的,你展示出来的别人理解的第一项,它如果看到的是 `and`,他就非常明确的知道这是一个逻辑与;但是他看到你这个 `&` 符号,他就会想一下你这块是不是做了一些比较 tricky 的事情。”不仅如此,改成 `and` 后由于运算符优先级明确,连外层冗余的圆括号也可以一并拿掉。

此外,代码在该段逻辑还存在以下重构与可读性优化空间:

- **第三方库调用的封装(Wrapper)**:计算月份天数时直接调用了 `calendar.monthrange(...)[1]`,代码长且下标 `[1]` 缺乏语义。读者很难立刻确定 `[0]` 和 `[1]` 谁是起始日、谁是结束日。建议封装成一个名为 `month_end_date` 之类的辅助函数。 - **长单行(One-liner)与临时变量**:非整月提取天数时,作者将 `range` 单独提取赋给 `days` 变量再拼装列表,这种拆分临时变量的做法值得肯定,避免了单行代码可读性恶化。 - **长逻辑与嵌套分支缺乏注释**:从第 52 行开始的跨月递归补齐逻辑过长,作者全篇除 docstring 外完全没有行内注释。尤其到第 60 行突然出现一个 `else`,读者需要向上翻近 20 行才能对应到第 41 行的判断(年份是否相等)。如果在分支处加上简单注释说明分支场景,阅读负担会大幅降低。 - **恒成立的冗余条件判断**:在第 63 行处理年份时,判断条件本意是检查两年份差值是否大于 1(效仿月份的处理),却误写成了判断是否相等;而在当前分支下年份必然不相等,导致判断恒成立。事实上,下方的 `range` 生成器在无差值时会自动产生空列表,该 `if` 完全可以移除或补充说明直接使用的理由。

---

[10:00](https://www.youtube.com/watch?v=ERosfjjY40Y&t=600s) API 输入输出格式设计与离谱的测试用例写法

在探讨完实现细节后,高天指出了该工具在接口设计上的体验问题:用户输入的是短横线格式(`-`),输出的日期列表却是斜杠格式(`/`),甚至作者自己在顶部的注释中都写错混淆了。这充分说明不同日期分隔符极易引起困惑。因此,函数应当优化输入兼容性,使接口能够同时容纳和识别横杠与斜杠。

代码审阅的最后一部分落在了测试文件上。测试文件采用了基于表格的测试风格(Table-based Test),将用例数据与断言逻辑分离,原本是非常规范优秀的实践;但其具体的执行方式却十分离谱:

```mermaid flowchart TD accTitle: 冗余测试用例执行流程 accDescr: 展示测试用例使用反射获取自身函数名并反查字典的低效重复设计

subgraph Data["测试数据集"] Cases["cases 字典 (包含测试数据 1 到 N)"] end

subgraph BadDesign["作者实现的冗余测试方法"] T1["test_1()"] --> G1["get_func_name()"] T2["test_2()"] --> G2["get_func_name()"] TN["test_n()..."] --> GN["get_func_name()"] end

G1 -->|"反射拿名字匹配 key"| Cases G2 -->|"反射拿名字匹配 key"| Cases GN -->|"反射拿名字匹配 key"| Cases

subgraph CorrectDesign["推荐的重构方案"] Loop["一个简洁的循环遍历 cases 字典并断言 (3行搞定)"] end ```

作者把所有数据抽离到了一个字典中,却在下方手写了几十个一模一样的测试函数(如 `test_1`、`test_2`、`test_3`……)。每一个测试函数内部没有任何独立逻辑,而是调用黑魔法函数 `get_func_name` 获取当前测试自身的名字,再拿着名字去数据字典里反查对应用例并执行。

面对这种实现,高天哭笑不得地指出:“我就完全无法理解他为什么要这么写了……你的每一个测试都是差不多的,为什么要把每一个测试单独的变成一个 test 呢?关键这些 test 也就叫 test 1 2 3 4 5 6 7,又不是你把它分门别类的归类到了一种 test 里。这个写法就是非常非常没有意义的,他们明明用这么三行代码就可以解决的问题,他写了好几十行。关键这还来了一个非常黑科技的函数 `get_func_name` 去拿到我当前运行的这个函数的名字,这是一件完全没有必要的事情。”整个测试框架写得冗长且毫无必要,只需用一个简单的循环遍历测试数据集进行断言即可优雅解决。

## Notable quotes > [05:00](https://www.youtube.com/watch?v=ERosfjjY40Y&t=300s) 大家千万不要在 Python 里用这个 & 符号来代替 and,这是非常错误的一种写法啊。 — 高天

## Mentioned 高天, date_range_prefix, Python, VS Code, GitHub, 知识星球

## Video description 其他Code Review:https://www.youtube.com/playlist?list=PLSo-C2L8kdSNr5yUJYhyDArnM4FU9iG1S

Code Review是提升代码水平最快的方式之一,这期视频我们来看一个处理时间的代码,看看他哪里写的还可以更好!

本次repo:https://github.com/randomseed42/date_range_prefix

[Source](https://www.youtube.com/watch?v=ERosfjjY40Y)

中文简报

码农高天审查开源代码 批位运算滥用与反射测试过度设计 以位运算符替代逻辑与并借反射函数名执行测试不仅严重破坏语义与可读性,更将原本三行循环即可完成的断言膨胀为数十行冗余样板。 本期视频对粉丝编写的日期前缀生成工具进行了系统性代码审阅。高天首先指出了项目管理与接口设计的不足,包括不应在仓库中提交 .vscode 私有配置、单字母变量命名易混淆,以及输入输出日期分隔符不一致的问题。接着重点批评了在 Python 中错误使用按位与运算符 & 代替逻辑运算符 and、深层分支缺乏行内注释和封装度不足等可读性坏味道。最后剖析了测试文件中用反射获取函数名、反查字典并机械重复几十个测试用例的“离谱”设计,演示了如何用简单的循环重构大幅精简测试代码。 在开源与正式项目中,不建议将包含本地配置的 .vscode 文件夹纳入版本控制提交到代码仓库。 (0:00) Python 逻辑判断中切勿用按位与运算符 & 代替 and,即便运行结果偶然一致也会破坏代码语义并误导读者。 (5:00) 测试用例将数据抽离到字典后,手写几十个 test_n 函数并用反射获取自身名称反查执行是毫无必要的过度设计,应直接循环遍历断言。 (10:00)

Reading summary

码农高天在对开源日期工具 `date_range_prefix` 的代码审查中指出,代码编写不仅要保证逻辑运行正确,更需遵循语义规范、保持工程整洁并摒弃画蛇添足的测试“黑魔法”。 版本控制与接口规范的工程细节 (0:00) 在项目文件组织上,作者将包含本地配置的 `.vscode` 目录直接纳入版本控制。高天指出,除个人多端同步等私有场景外,在正规开源项目中强烈建议不要提交此类编辑器配置。在接口体验方面,函数输入要求短横线格式(`-`),返回值却采用斜杠格式(`/`),甚至作者自己在文档注释中都混淆了二者。高天认为接口设计应提升输入兼容性,同时支持横杠与斜杠分隔符,以避免给调用者带来不必要的困扰。 拒绝单字母与歧义缩写的命名重构 (0:00) 针对代码中的变量命名,高天提出应避免使用单字母如 `s` 和 `e` 来代表解析后的起止时间对象,也不建议直接覆盖原变量导致类型变化,改用具名变量 `start_dt` 更有利于长期维护。此外,返回值列表被命名为 `rng`,在阅读时极易与随机数生成器(Random Number Generator)混淆。高天主张在非必须极度缩写的场景下应直接展开命名为 `date_range` 或 `result`,使代码意图一目了然。 语义规范与控制流中的冗余代码 (5:00) 在判断起止日期是否覆盖整月时,代码误将按位与运算符 `&` 当作逻辑与 `and` 使用。高天强调编程中“语义是有意义的”,即便利逻辑结果吻合,使用 `&` 也会误导读者猜测是否存在特殊底层操作;改用 `and` 还能利用原生优先级移除冗余的括号外壳。同时,代码中直接调用 `calendar.monthrange(...)[1]` 欠缺语义,建议封装为如 `month_end_date` 的辅助函数。在跨年分支中,代码还遗留了判断年份是否相等的恒成立冗余 `if`,直接依赖生成器特性或清理无意义分支能大幅降低阅读负担。 测试设计切忌过度复杂的“黑魔法” (10:00) 该项目的测试文件虽采用了用例与断言分离的表格驱动理念,但在落地方式上存在严重问题。作者将测试用例抽取到字典后,手写了数十个命名为 `test_1`、`test_2` 的一模一样的方法,并通过名为 `get_func_name` 的反射技巧获取自身函数名再去反查字典。高天指出这种“黑科技”完全没有必要,既没有做到对测试场景分门别类,又平添了大量样板代码,实际上只需三行简单的遍历循环即可优雅完成所有测试断言。 高质量的代码不仅依赖算法逻辑的自洽,更体现在合乎常理的工程直觉、清晰的语义表达以及化繁为简的测试设计中。

Source quotes

[5:00] 高天: 大家千万不要在 Python 里用这个 & 符号来代替 and,这是非常错误的一种写法啊。

Original transcript

[0:00] 我们呼声最高的code review 系列 今天开始 正式改版回归了在新的改版中我们会使用录制而不是直播的方式希望给大家带来节奏更快信造比更高的Code Review让大家用更短的时间收获更多的知识目前呢 我们的code review 只支持在知识星球里报名每次code review的视频我会发到B站同时我还会总结一份这次code review的要点发到直星球里好,那我们这次code review 代码是叫做 date range prefix这是这位粉丝呢写的一小段函数这个函数的目标非常明确还是很适合拿来做CodeReview的对象我们首先来看一下它的repo啊repoly非常简单一个核心的派档代码对应的测试代码license和readme一个Kit Ignore另外,他上传了一个VSCode的Local Settings。在这里我个人是强烈建议不要上传这个东西的它这里面主要应该是设置了一下unitest但是使用你这个report呢它不一定用VSCode一般来说我们建立repple是不太会把这个.vscode文件件传上来的当然如果你是单纯的自用就是为了在不同电脑上同步方便也未尝不可对于比较大的开源项目这件事是绝对不会发生的好 那我们现在来正式看它的代码啊我使用的是网页版的VS Code它整个代码就写了这么一个函数这个函数写了一段注释是非常不错的这个注视本身没有那么容易读躲大家可以看一下单纯的从他这段英文能不能看懂他要干什么我当时反正没读做但是他后面给出了若干个非常详尽的例子有了这些例子之后 明显就更容易理解了比如他这里给的输入是开始是2023年1月30号结束是2023年3月1号他就返回了一个listlist里面有四个数据1月30号1月31号2月和3月1号那我们感受一下他就是要表达一个时间段这个时间段是以天为单位的但是呢 他不能把每一天都单独的列出来所以如果有整月或者整年他可以列这个月或者这一年否则的话他要把每一天都列出来比如下面这个例子1月1号到3月31号就是2023年1月2月和3月这里注意一下这时候出现了一个明显的错误本来应该是斜杠的它变成横线了对吧这个就是相对比较低级的食物啊那下面呢就是不给start跟end的话是当天然后还展示了一个整年的情况我的建议是这两个例子换个个因为上面是天整月的然后你接下来是个整年的 再给一个不给argument的情况这样理解上会容易点上来先处理default argument 如果没给start的话 直接让它是today如果没给end的话直接让它是start这里判断用了意思啊很好接下来把start跟end从string变成时间这里我其实不太推荐使用S跟E这么简单的变量名单字母的变量棉我们尽量还是要避免因为看到后面你特别容易忘了哪个是开始哪个是结束 你要反映一下那有人说如果我把这个start的string直接在复制回给start变成type 合适不合适呢其实也不太好因为这样star这个variable在你同一个函数里就有过两种不同的type了也是容易引起误会啊所以这里可能可以考虑比如说star下方线t之类的相对来说更容易看懂是什么的名字这里判断了一下尾是不是大于头然后raise一个value error没有问题下面返回值的初始化RNG这个名字真的不太好我看到rng的第一反应是random number generator就是大家真的没有必要在变量名上尝试去给它压缩的无限短这件事是没有什么意义的只会让你后面的代码越看越乱所以这个名字我也是建议改一下啊我甚至不太确定它到底是要什么意思 是range吗接下来就是它的核心逻辑啊如果起始跟结束的年份是相等的然后如果他们俩月份也是相等的那就只需要把这一天一天输出出来对吧这里他把这个month重新复制了一下不是不行啊我是觉得这块没什么必要因为你把慢复值了叶为什么不复值呢你就会出现这种s.year 然后man 其实没什么意义啊就S.month完全是可以的这里是如果是一整个月的情况啊开始的时候是1号结束的时候是最后一天这里出现了第一个极大的问题这个end符号用在这里结果上是对的但是语意上是不对的大家千万不要在python里用这个end符号来代替end这是非常错误的一种写法啊我很多次跟大家强调语义是有意义的就哪怕你运行的结果是没错的 你展示出来的别人理解的 [5:00] 第一项 它如果看到的是andand 它就非常明确的知道这是一个逻辑语语但是他看到你这个end符号他就会想一下你这块是不是做了一些比较tricky的事情然后这个部分每个月的最后一天是不一样的对吧所以他使用一下第三方库我建议在这里也要有一个rapper不要直接用这一串 因为看代码的人不知道这个方括号1是什么意思当然他可以猜测方框20是开始那天 方框21是结束那天但是他很难去确定这里你自己定义一个函数,比如说叫Month and Date然后你把你这一大串给放进去你代码的可读性影响提升了非常多如果是整月的情况下他这块加等于了一个list这也没有什么问题里面用的是 f string 也没有毛病这里的format大家可以稍微学习一下携两位不够的用零填充如果不是整月把每一天都拿出来构建一个list+等于到这个RNG上 这也没问题而且我还挺喜欢他把这个range单独复制给一个变量叫做dace的大家看如果我把这个range直接写到这个one liner里面是不是可读性就变差了虽然还是基本能读懂啊但是我还挺喜欢他重新复制一下的接下来一种情况 如果是一整年 同样的不要用这个and符号如果不用这个AND符号 你甚至都可以不要括号了 多开心如果既不是一整个月也不在同一个月他就开始做这一串这里我们就会发现可读性明显的下降了为什么呢 因为他没有跟我们解释他在干什么在这种相对复杂的逻辑里,你一定要注意写诸事啊他整篇代码除了那个函数下面的dogstream之外就基本没有写注释于是这样相对复杂的逻辑里我们就必须要通过它的代码读懂它在干什么好 上面这个部分就是把开始那个月对应的range找出来 放到这个rng里我们可以看到第52行代码就已经过长了对不对其中这个calendar month range的功不可没啊然后这里他用了一个地规 没有问题这个地规是必然能结束的如果两个月的月份有一个月以上的差距就把中间那几个整月补上去然后把最后那一个月对应的range补上去其实我这么一解释你是不是觉得容易懂了代码看起来不那么复杂但是你刚刚开始看这个代码的时候是不是觉得有点懵这就是注视的作用是我在边上帮你给注释你听了我的注释之后一下就把这个代码看懂了这就是为什么相对复杂的逻辑我们要写一写注释啊写一点就够了好 提问 请问60行的这个else对应的if是什么大家可以看自己需要多长时间才能反应过来啊在读了刚才那些逻辑之后突然看到一个else我们很有可能是反应不过来他对应的是哪个if的这个时候我们要往上找发现这个if在41行六十行这个else对应的是s和e的ear不等的时候那这个时候我们想象一下如果这个else里面有一个非常简单的注释告诉我们这个else是什么case是不是可毒性就高了很多那年这个部分的处理呢和月非常相似也是掐头去围然后for loop处理中间但是我们看一下63号还有没有人记得刚才60行的条件是什么哪怕我们只起了一个如此简单的注释我们就会发现下面if statement是横成立的在月份的时候他比的是这两个月的差是不是大于1但是在年份的时候 它比的是他俩是否相等所以这里比较的应该也是他们俩的差值是不是大于1当然逻辑上说这个if可以直接拿掉对吧因为下面的range会控制你产生这个list的长度假如没有单独的整年他下面就会加一个空的list当然上面的月份也是一样对吧这个if拿掉逻辑还是成立的那拿与不拿我觉得都可以因为每个人读代码的时候感觉是不一样的有的人喜欢显示的if有的人呢 就觉得是不是有这个显示的if无所谓 只要逻辑成立就可以了如果大家把这个if整个拿掉的话我还是推荐大家在这里稍微做一下注释说明白为什么这个range可以直接用好 在这代码的实现我们过了一下它的功能本身有没有什么可说的呢我觉得最起码有一点是非常明确的大家有没有意识到它的输入日期格式和它的输出日期格式是不一样的有的是用杠的 有的是用斜杠的这件事本身对于用户来说就是一个非常困惑的事就我输入的是日期string,我输出的是个list of 日期string,为什么这两个日期的格式它能不一样呢讲到这我还突然意识到他上这个注释给的也不对啊这有充满的 [10:00] 说明了杠杠和斜杠确实特别容易搞混所以呢 我给他的建议是 是不是可以考虑把这个input设置成多种格式都可以识别的就是他既能处理横杠又能处理斜杠这里怎么实践对吧也是可以思考一下好 代码本身看完了我们看一下它的测试这个测试文件看到这个部分的时候我实际上是非常开心的我很喜欢这种table-based test就是你把你的数据放到一起把你的逻辑放到一起这也是我们之前提到过的数据跟逻辑分离 对吧你可以非常清晰的看到他想测试的输入是什么输出是什么这很好然而我看到下面这一串我还是有点崩溃的他是把数据给放到一起了但是他的测试是写了无数个test每一个test去根据这个test的名字找到Cases对应的数据然后再跑大家会发现他每一个测试的代码是完全一样的我就完全无法理解他为什么要这么写了你的每一个测试都是差不多的为什么要把每一个测试单独的变成一个test呢关键这些TES也就叫TES的1234567又不是你把它分门别类的归类到了一种test里这个写法就是非常非常没有意义的他们明明用这么三行代码就可以解决的问题他写了好几十哈关键这还来了一个非常黑科技的函数getfunkname去拿到我当前运行的这个函数的名字这是一件完全没有必要的事情所以测试这个部分的framework做的还是有比较大的问题的好这就是我们这次的code review 希望大家可以多多关注这个系列如果大家喜欢的话我们未来还会给大家带来更多的代码code review如果未来不想看这种视频了就不要意见残联了字幕志愿者 杨茜茜