哪些代码是 Code Review 中的大忌?—— 以 Python 为例

请添加图片描述

Code Review 首要达成的结果是更好的可读性

在此基础上才是进一步发现项目的 Bug、处理性能优化上的问题。

因为,编码是给人看的,不是给计算机(Coding for human, NOT computer)。

一. 滥用缩写命名 Overusing abbreviation

大部分业务,尤其是不是直接暴露在前端的业务,不需要考虑混淆的设计,别因为少打两个字,让你的同伴都搞混了!

# Bad. 自成体系的缩写
lst = [1, 2, 3, 4, 5]
sqrd_lst = [num**2 for num in lst]
fltd_sqrd_lst = list(filter(lambda x: x % 2 == 0, sqrd_lst))
# Good. 一眼看出变量名的含义
riginal_numbers = [1, 2, 3, 4, 5]
squared_numbers = [num**2 for num in original_numbers]
filtered_squares = list(filter(lambda x: x % 2 == 0, squared_numbers))

二. 语法糖可能是毒药 Syntax Sugar can be Poison

语法糖是常见的程序员炫技手段,但即使对写下这段代码的人,经过一段时间后,也未必能在第一时间读出这段代码的含义。

例如在 Python 中:

  1. 使用布尔操作符作为条件判断
    第一段炫技代码,不熟悉的同学可能第一反应是 result=True
# 炫技,可读性差
is_valid = True
result = is_valid and "Valid" or "Invalid"

# 等价,可读性更好
result = "Valid" if is_valid else "Invalid"
  1. 使用列表推导式处理嵌套列表
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
  1. 过度追求“简洁”的 lambda 表达式
    lambda 表达式用在 sorted 中做为排序参数是比较常用的,但过度追求单行表达,是不可取的,除了可读性差,还违背了程序设计的单一职责原则

单行、可读性差版本:

students = [
    {"name": "Alice", "age": 25, "grade": 90},
    {"name": "Bob", "age": 22, "grade": 85},
    {"name": "Charlie", "age": 28, "grade": 88}
]

sorted_students = sorted(students, key=lambda x: (lambda y: (lambda z: z["grade"] - y["age"])(y))(x))

分离职责,可读性好版本:

def calculate_score(student):
    return student["grade"] - student["age"]

sorted_students = sorted(students, key=calculate_score)

当然,语法糖也有少部分是增加可读性的,可以作为代码规范使用:

big_number = 1_000_000_000
# equivalent to big_number = 1000000000

1 < x < 10
# equivalent to 1 < x and x < 10

三. 不可预测的代码 Unpredictable Code

好代码是可预测的,坏代码是给人惊吓的。

一种是由于开发人员基础不扎实无意识造成的:
例如:
使用可变变量作为参数

# WRONG:
def add_numbers(a, b, result=[]):
    result.append(a + b)
    return result

# Example usage
print(add_numbers(1, 2))   # Output: [3]
print(add_numbers(3, 4))   # Output: [3, 7]
print(add_numbers(5, 6))   # Output: [3, 7, 11]

# CORRECT:
def add_numbers(a, b, result=None):
    if result is None:
        result = []
    result.append(a + b)
    return result

# Example usage
print(add_numbers(1, 2))   # Output: [3]
print(add_numbers(3, 4))   # Output: [7]
print(add_numbers(5, 6))   # Output: [11]

另一种,是开发设计的偷懒、或者未进行事先沟通自作主张。

最常见的是更改接口参数类型,返回不符合预期的结构数据。比如不允许为空的字段返回了空,API 版本没有变化的情况下,增加了必传的参数等等

再如,状态码与实际的情况不符合。

虽然开发人员处理了几种已知的错误,但是状态码一直是 200,对于调用方,如果使用 status.OK 则永远返回 True,处理不到这些异常情况。

from flask import Flask, jsonify
app = Flask(__name__)

@app.route('/delete-file/<file_id>', methods=['DELETE'])
def delete_file(file_id):
    try:
        # Delete the file
        # ...
        return jsonify({"status": "success"})
    except FileNotFoundError:
        return jsonify({"status": "error", "message": "File not found"})
    except PermissionError:
        return jsonify({"status": "error", "message": "Permission error"})

if __name__ == '__main__':
    app.run()

正确的写法,应该使用对应的状态码,确保其他框架可以信任这个结果:

# Following the Principle of Least Astonishment in error handling
from flask import Flask, jsonify
from werkzeug.exceptions import NotFound, Forbidden

app = Flask(__name__)

@app.route('/delete-file/<file_id>', methods=['DELETE'])
def delete_file(file_id):
    try:
        # Delete the file
        # ...
        return jsonify({"status": "success"})
    except FileNotFoundError:
        raise NotFound(description="File not found")
    except PermissionError:
        raise Forbidden(description="Permission error")

if __name__ == '__main__':
    app.run()

Bonus: 有没有可以抄的解决方法?

  1. 参考大厂的代码风格规范

Google 开放了不少常见语言的代码规范:
https://google.github.io/styleguide/

请添加图片描述

小米也有数据库设计,SQL 相关的规范:
https://github.com/XiaoMi/soar

如果接手一个新的语言或工具,还可以在搜索资料时加一个 best pratice 看看其他人的经验。

  1. 借助插件或 CI 工具

对于常见的规范单行代码长度、空格等,可以使用 ESLint、Pylint,、 Black (for Python) 等,直接格式化代码,或者借助工具查错

  1. 多 Review 多沟通
    工作中的大部分代码不是你一个人蛮干,自己的思维局限性,可以通过他人的视角打破。

Ref:

  1. Syntactic Sugar in Python
  2. 7 simple habits of the top 1% of engineers

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/319287.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

软件工程:黑盒测试等价分类法相关知识和多实例分析

目录 一、黑盒测试和等价分类法 1. 黑盒测试 2. 等价分类法 二、黑盒测试等价分类法实例分析 1. 工厂招工年龄测试 2. 规定电话号码测试 3. 八位微机测试 4. 三角形判断测试 一、黑盒测试和等价分类法 1. 黑盒测试 黑盒测试就是根据被测试程序功能来进行测试&#xf…

4_【Linux版】重装数据库问题处理记录

1、卸载已安装的oracle数据库。 2、知识点补充&#xff1a; 3、调整/dev/shm/的大小 【linux下修改/dev/shm tmpfs文件系统大小 - saratearing - 博客园 (cnblogs.com)】 mount -o remount,size100g /dev/shm 4、重装oracle后没有orainstRoot.sh 【重装oracle后没有orains…

【面试突击】并发编程、线程池面试实战

&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308; 欢迎关注公众号&#xff08;通过文章导读关注&#xff1a;【11来了】&#xff09;&#xff0c;及时收到 AI 前沿项目工具及新技术 的推送 发送 资料 可领取 深入理…

2024--Django平台开发-Django知识点(七)

频率超高的问题 Redis的问题虚拟环境mysqlcient和pymysql短信服务&#xff0c;一期用的是腾讯云短信 虚拟环境 可以用来创建虚拟环境的&#xff1a; virtualenv这个模块&#xff0c;简单易上手&#xff0c;推荐 小白不建议&#xff0c;conda&#xff0c;如果大家用这个&…

NSSCTF Round# 16 Basic pwn方向题解

pwn nc_pwnre 没有附件&#xff0c;nc直接连接 给了一段汇编代码&#xff0c;让gpt翻译一下 这段汇编代码是一个循环&#xff0c;它对存储在ebpi位置的字符串进行处理。让我逐步解释一下每个指令的作用&#xff1a;mov eax, [ebpi]: 将ebpi位置的值加载到eax寄存器中。 add e…

【汇编要笑着学】汇编模块化编程 | call和ret调用指令 | jmp跳转指令 | inc自加指令

Ⅰ.汇编模块化编程 0x00 一个简单的例子 我们了解模块化编程前先给出一个例子&#xff0c;方便大家快速了解。 SECTION MBR vstart0x7c00 ; 起始地址编译在0x7c00mov ax,cs mov ds,ax mov es,axmov ss,axmov fs,axmov sp,0x7c00 ; 上面这些都没什…

系列十、Spring Security登录接口添加验证码

一、Spring Security登录接口添加验证码 1.1、概述 一般企业开发中&#xff0c;登录时都会有一个验证码&#xff0c;基于Spring Security的登录接口默认是没有验证码的&#xff1f;那么如何把验证码功能集成到Spring Security的登录接口呢&#xff1f;请看下文&#xff01; 1.…

基于SSM的仓库在线管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

C++学习笔记——输入、输出和文件

目录 一、标准输入输出 2.1下面是它们的基本用法 解释 二、格式化输入输出 2.2下面是一个示例 解释 三、文件读写 3.3下面是一个文件读写的示例 解释 四、异常处理和错误检测 4.1下面是一个示例 解释 五、一个实例代码 5.1如何读取 CSV 文件&#xff0c;并计算每…

大厂是怎么做支付系统的流程容错的?

点击下方“JavaEdge”&#xff0c;选择“设为星标” 第一时间关注技术干货&#xff01; 1 单据关联 如某些订单域内部的多种单据间存在关联关系一样&#xff0c;支付设计上也有单据间关联设计。如所有逆向过程都须持有正向的单据&#xff0c;因此退款须关联到原来的支付&#…

LTESniffer:一款功能强大的LTE上下行链路安全监控工具

关于LTESniffer LTESniffer是一款功能强大的LTE上下行链路安全监控工具&#xff0c;该工具是一款针对LTE的安全开源工具。 该工具首先可以解码物理下行控制信道&#xff08;PDCCH&#xff09;并获取所有活动用户的下行链路控制信息&#xff08;DCI&#xff09;和无线网络临时…

为了这口醋,包的这饺子。为了Selenium,学有限的CSS,逐步替换XPATH

Learn about CSS rules and pseudo-classes to help you move your XPATH locators to CSS. 1. 最基本IdElement TypeDirect ChildChild or Sub-ChildClass 2. 深入一点Next SiblingAttribute ValuesChoosing a Specific Match Sub-String Matches 3 参考资料 In order for Sel…

Java零基础教学文档第五篇:jQuery

今日新篇章 【jQuery】 【主要内容】 jQuery简介 jQuery安装 jQuery语法 jQuery选择器 jQuery事件处理 jQueryDOM操作 jQuery元素遍历 jQuery过滤 jQuery其它方法 【学习目标】 1.jQuery简介 1.1 jQuery简介 jQuery 库可以通过一行简单的标记被添加到网页中。 1.…

java自动化将用例和截图一起执行测试放入world中直接生成测试报告【搬代码】

1.首先我们得用例写好之后放入文档中&#xff0c;把不用的案例类型、前置条件去掉之后&#xff0c;如图&#xff1a; 放到桌面后&#xff0c;先看执行结果&#xff1a; 直接上代码 package com.znzdh.qitagongju;import jxl.Sheet; import jxl.Workbook; import org.apache…

了解集群,以及集群是什么?

每个集群即一个独立运行的文档数据库&#xff0c;分片集群架构由路由&#xff08;mongos&#xff09;、配置&#xff08;config&#xff09;和分片&#xff08;shard&#xff09;组成。 数据读写请求经mongos分发&#xff0c;通过查询config信息&#xff0c;并行分配到相应sha…

C语言之字符串和指针

目录 用数组实现的字符串和用指针实现的字符串 █用数组实现的字符串str █用指针实现的字符串ptr 注意 用数组和指针实现字符串的不同点 字符串数组 用数组实现的字符串的数组——二维数组 用指针实现的字符串数组——指针数组 注意 字符串和指针有着紧密的联系&#…

力扣(105. 从前序与中序遍历序列构造二叉树,106. 从中序与后序遍历序列构造二叉树)

题目1链接 题目1&#xff1a; 思路&#xff1a;使用前序确定根&#xff0c;使用中序分左右子树&#xff0c;分治法。 难点&#xff1a;如何控制递归确定左右子树。 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* T…

【STM32】FLASH闪存

1 FLASH闪存简介 本节所指STM32内部闪存&#xff0c;即下载程序的时候&#xff0c;程序存储的地方。&#xff08;非易失性&#xff09; STM32F1系列的FLASH包含程序存储器、系统存储器&#xff08;bootloader&#xff0c;不允许修改&#xff09;和选项字节三个部分&#xff0…

华西建筑智能化寻找志同道合的创业团队

我今天四十多了&#xff0c;之前也创过业&#xff0c;做软件开发系统集成的。 19年进入华西建筑装饰工程有限公司负责机电安装及弱电智能化版块。后公司成立建筑智能化事业部&#xff0c;我负责。现在想全身心打造施工企业项目管理平台&#xff0c;同时进军智慧康养领域。我想…

1.5矩阵元素的引用

通过下标来引用矩阵的元素 A(3, 2)表示A矩阵第3行第2列的元素。 >> arr [1,2,3;4,5,6]; >> arr(4, 5) 10arr 1 2 3 0 04 5 6 0 00 0 0 0 00 0 0 0 10>> 如果引用元素超过矩阵的大小将自…