【读书笔记】python代码整洁之道


前言

书籍阅读笔记
《Python 代码整洁之道:编写优雅的代码》[ 美 ] 苏尼尔·卡皮尔(Sunil Kapil) 著


python代码整洁之道

关于python

命名

使用小写字母命名变量和函数,并用下划线连接单词

类的私有成员(属性/方法):以一个下划线为前缀

防止名称混淆:以两个下划线为前缀

类名:大驼峰方法,即每个单词的首字母大写

常量名:大写字母

类方法:使用 self 作为第一个关键字参数


连接字符串:使用 "".join() 方法(如 "".join([a, b]))而不是使用内置的字符串连接符(如 a += b 或者 a = a + b

在判断是否为 None 时,始终使用 is 或者 is not (如 if a is not None:,而非 if a:

如果函数有返回值,确保任何执行此函数的地方都返回该值(使用 return None

需要检查前缀(字符串的开头部分)和后缀时,考虑 "".startswith()"".endswith()而不是切片([]选取)

对两个对象类型进行比较时,考虑 isinstance() 而不是 type()(如 if isinstance(user_ages, dict):

比较 Boolean值,使用 if is_empty:

当进入 with 代码块时,会调用 __enter__ 方法获取资源,并在离开 with 代码块时调用 __exit__ 方法释放资源

with connection.NewProtocol(host, port):  # connection.py 引用该类
    transfer_data()

文档字符串

文档字符串(多行注释:三重引号)是其对象的 __doc__ 的特殊属性

def boo(a, b):
    """这是一个加法函数"""
    return a+b
boo.__doc__
  • 如果在代码中指明了变量类型,就没必要在文档字符串里写参数信息了
  • 在文件的顶部放置一个模块级文档字符串来简要描述模块的用法(放在 import 之前)
  • 使用文档生成工具

控制结构

列表推导:允许在有或没有 if 条件的情况下,在列表中做到以类似于 for 循环的方式解决问题

filtered_data = [item for item in filter if item]
  • map(映射)和 filter(筛选)相比,更具可读性
  • 没有复杂条件或复杂计算的情况下使用

使用函数,而不是把 lambda 表达式赋值给一个特定标识符(变量名)

生成器(with open(file_name) as fread:)和列表推导的主要区别:列表推导将数据保存在内存中

不要在循环后使用 else

  • 只有当从循环中正常退出时,else 子句才会执行(即在循环结束后执行一个额外的操作);使用中断关键字退出循环,则不会

range 不将数据保存在内存中,只存储 startstopstep

  • 可以对两个 range 数据做比较 range(4) == range(4)
  • 可以切片 range(10)[2:]
  • 在处理数字时,在循环中尽可能多地使用迭代器(for item in range(10):

引发异常

异常帮助 API 或库的使用者了解在函数执行期间失败的原因

在发现当前代码块有运行失败的可能时,抛出异常,而非返回 None

finally 块中的代码总是会被运行。无论是否引发异常,都可以使用 finally 来确保关闭或释放文件或资源

finally:
    myfile.close() 

创建自己的异常类(如 class UserNotFoundError(Exception):

  • 要确保知道异常的范围:为自定义的异常设置一组特定的边界

捕获每一个异常,指明异常的类型(如 except NoneType:),而非使用 except 处理所有异常

了解一些由第三方库抛出的常见异常

考虑添加日志

except ClientError as e:
    logger.error("Received error: %s", e, exc_info=True)

数据结构

集合

类型:set;形式:{}

需要经常访问数据元素,并且在 O(1) 时间内访问这些项,可以考虑使用集合

集合元素不能重复,不支持索引访问,散列查询速度快(集合是使用散列表实现的),可用作其他数据结构的键

namedtuple

实际上是一个带有数据名称的元组,返回和访问数据时使用

from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
p = Point(10, 20)
p.x  # 10
p[1]  # 20
p._asdict()  # 将命名元组转换为字典
Point._make(point_list)  # 将列表转换为命名元组

值在初始化后不可更改,字段名必须是字符串

有多个值需要上下传递时,考虑 namedtuple ;元组不会为 tuple 中的数据提供上下文或名称,而 dict 不具有不可变性

Unicode

使用十六进制数字,为几乎所有字符提供了唯一的标识(代码点,code point)

UTF-8 用 1-4 个字节(8/16/24/32位)来表示一个 Unicode 字符,兼容ASCII

  • Python 解释器使用 UTF-8 编码
  • 编码:将字符映射到位模式

生成器

用列表存在内存泄漏的风险(列表数据存储在内存中)

使用 yield 关键字来生成数字,可作为迭代器的返回值

def get_prime_numbers(lower, higher):
    for possible_prime in range(lower, higher):
        if is_prime(possible_prime):
            yield possible_prime
        yield False

zip

将多个可迭代对象(列表、元组、等长序列)中对应位置的元素打包成元组

list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
combined = list(zip(list1, list2))
# [(1, 'a'), (2, 'b'), (3, 'c')]

内置库

collections:有很有用的数据结构,如 namedtupledefaultdictorderddict

re:正则表达式

tempfile:创建一次性临时文件

itertools:排列和组合

subprocess:创建多个进程

pickle:序列化和反序列化 Python 对象

__future__:一个伪模块,支持与当前解释器不兼容的新语言特性

  • 18
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值