美文网首页@IT·互联网
哪些代码是 Code Review 中的大忌?—— 以 Pyth

哪些代码是 Code Review 中的大忌?—— 以 Pyth

作者: FesonX | 来源:发表于2024-01-13 11:15 被阅读0次

    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/

    Google Style Guide

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

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

    1. 借助插件或 CI 工具

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

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

    Ref:

    1. Syntactic Sugar in Python: https://medium.com/analytics-vidhya/syntactic-sugar-in-python-3e61d1ef2bbf
    2. 7 simple habits of the top 1% of engineers: https://read.engineerscodex.com/p/7-simple-habits-of-the-top-1-of-engineers

    相关文章

      网友评论

        本文标题:哪些代码是 Code Review 中的大忌?—— 以 Pyth

        本文链接:https://www.haomeiwen.com/subject/okyxodtx.html