找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1622

积分

0

好友

232

主题
发表于 3 天前 | 查看: 8| 回复: 0

图片

《Python工匠》是一本专注于提升Python代码质量的进阶读物,尤其适合希望强化编码能力的开发者。本书第一章聚焦于代码的“门面”——变量与注释,它们是代码中最接近自然语言的部分,直接决定了代码的可读性与可维护性。

《Python 工匠》简介

本书作者朱雷(piglei)拥有十余年后端开发与架构设计经验。全书分为五大部分共13章,结构清晰。除第10章与第11章外,其余章节内容独立,读者可按兴趣选读。每章均包含三大板块:基础知识、案例故事与编程建议。

图片

在深入学习前,建议准备以下工具:

  • 命令行工具(已安装Python3),推荐使用Warp。
  • IDE,推荐使用PyCharm。

1. 基础知识

1.1. 变量

声明和赋值

Python作为动态类型语言,无需预先声明变量类型,可直接赋值。

>>> author = 'piglei'
>>> author
'piglei'

Python支持一行内同时操作多个变量,例如交换两个变量的值,这一特性在排序算法实现中非常有用。

>>> author, reader = 'piglei', 'Java一条人'
>>> author, reader = 'Java一条人', 'piglei'
>>> author
'Java一条人'
>>> reader
'piglei'
解包

变量解包允许我们将一个可迭代对象的所有成员一次性赋值给多个变量。

>>> usernames = ['piglei', 'raymond']
>>> author, reader = usernames
>>> author
'piglei'
>>> reader
'raymond'

使用星号表达式(*variables)可以进行动态解包,贪婪地捕获多个值。

>>> data = ['piglei', 'apple', 'orange', 'banana', 100]
>>> username, *fruits, score = data
>>> username
'piglei'
>>> fruits
['apple', 'orange', 'banana']
>>> score
100
单下划线变量名

单下划线 _ 常作为无意义的占位符,用于忽略某些变量。

# 解包时忽略第二个变量
>>> author, _ = usernames
# 解包时忽略中间所有变量
>>> username, *_, score = data

在Python交互式命令行中,_ 默认保存上一个表达式的返回值。

给变量注明类型

为解决动态类型带来的可读性问题,可采用类型注解。

from typing import List

def remove_invalid(items: List[int]):
    """ 剔除 items 里面无效的元素
    :param items: 待删除的对象
    :return:
    """

提示Listtyping模块提供的类型注解工具。Python 3.9开始,内置的list也支持泛型语法,可优先使用list[int]

添加类型注解能提升代码可读性、获得更智能的IDE提示、并方便进行静态类型检查。

变量命名原则
  1. 遵循PEP 8:普通变量使用蛇形命名法(snake_case),常量使用全大写(MAX_VALUE),内部使用变量加下划线前缀(_local_var),避免与关键字冲突可加下划线后缀(class_)。
  2. 描述性要强:在合理长度内,变量名应尽可能精确描述其内容,例如file_chunks优于data
  3. 要尽量短:命名需结合上下文,在已知情境下可使用较短但明确的名称。
  4. 要匹配类型
    • bool类型常用is_has_开头。
    • int/float类型常用portageuser_idmax_lengthuser_count等。
    • 避免使用名词复数表示数量,易与列表类型混淆。
  5. 超短命名:在约定俗成的场景下可使用,如索引i, j, k、整数n、字符串s、异常e等,但应优先使用更精确的名称。

1.2. 注释

Python注释主要包括代码内注释(#)和函数文档字符串。

# 用户输入可能会有空格,使用 strip 去掉空格
username = extract_username(input_string.strip())

class Person:
    """人
    :param name: 姓名
    :param age: 年龄
    :param favorite_color: 最喜欢的颜色
    """
    def __init__(self, name, age, favorite_color):
        self.name = name
        self.age = age
        self.favorite_color = favorite_color
用注释重复代码

注释应提供代码之外的信息,解释“为什么”这么做,而非简单复述代码。
不佳示例

# 调用 strip() 去掉空格
input_string = input_string.strip()

良好示例

# 如果直接把带空格的输入传递到后端处理,可能会造成后端服务崩溃
# 因此使用 strip() 去掉首尾空格
input_string = input_string.strip()
指引性注释

这种注释概括代码块功能,充当“代码导读”。但当逻辑可以提炼为独立函数时,应优先使用有意义的函数名。
使用指引性注释

# 初始化访问服务的 client 对象
token = token_service.get_token()
service_client = ServiceClient(token=token)
service_client.ready()

优化为函数调用(更佳):

service_client = make_client()
弄错接口注释的受众

接口文档应面向函数使用者,着重描述功能、参数和返回值,而非内部实现细节。实现细节应放在函数内部的代码注释中。

2. 案例故事

面试题:实现“魔法冒泡排序”,规则是所有偶数都比奇数大。

>>> numbers = [23, 32, 1, 3, 4, 19, 20, 2, 4]
>>> magic_bubble_sort(numbers)
[1, 3, 19, 23, 2, 4, 4, 20, 32]

一个初级实现可能功能正确但可读性差。优化版本通过以下改进显著提升了代码质量:

  1. 使用有意义的变量名(如 stop_position, should_swap)。
  2. 引入解释性临时变量(如 current_is_even)。
  3. 添加指引性注释阐明交换条件。
  4. 代码逻辑更清晰,易于理解。

3. 编程建议

3.1. 保持变量的一致性

保持变量命名和类型的一致性。不要将同一个变量名重复用于指向不同类型的对象。

3.2. 变量定义尽量靠近使用

避免在函数开头集中定义所有变量。应将变量定义移动到实际使用它的代码块附近,缩短“定义”与“使用”的距离,提升可读性。

3.3. 定义临时变量提升可读性

将复杂的条件表达式赋值给一个具有描述性的临时变量,可以大大提高代码的可读性。

# 优化前
if user.is_active and (user.sex == 'female' or user.level > 3):
    ...

# 优化后
user_is_eligible = user.is_active and (user.sex == 'female' or user.level > 3)
if user_is_eligible:
    ...

3.4. 同一作用域内不要有太多变量

函数内变量过多通常意味着函数过于复杂、承担了太多职责。解决方法是:

  1. 分组建模:使用数据类(如dataclass)或简单类将相关变量组织起来。
  2. 拆分函数:这是降低复杂度的根本方法,将大函数拆分为多个职责单一的小函数。

3.5. 能不定义变量就别定义

不要为了未来可能但不确定的变动而预先定义变量,这可能会牺牲代码当下的简洁性和可读性。

3.6. 不要使用 locals()

避免使用locals()来收集变量进行传递(例如在Web框架中渲染模板时)。虽然这样做代码看似简洁,但违反了“显式优于隐式”的原则,会隐藏实际依赖的变量,大幅降低代码可读性。

3.7. 空行也是一种注释

恰当地使用空行来区分不同逻辑代码块,可以有效提升代码的视觉结构和可读性。

3.8. 先写注释,后写代码

在编写函数体之前,先写好函数接口注释。这能迫使你思考函数的单一职责,并确保不会遗漏重要的文档。如果你无法用几句注释清楚描述函数功能,那么这个函数可能就需要重新设计。养成这个习惯能从根本上提升后端代码的设计质量。




上一篇:云服务器带宽Mbps与MB/s换算指南:网速单位详解与下载速度计算
下一篇:网络安全警报:攻击者滥用PuTTY客户端实现Windows环境横向移动与数据窃取
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-24 20:52 , Processed in 0.212604 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表