《Python工匠》读书笔记

唉,学

变量与注释

前言

比较以下两行代码:

1
2
3
4
# 去掉 s 两边的空格,再处理
value = process(s.strip())
# 用户输入可能会有空格,使用 strip() 去掉空格
username = extract_username(input_string.strip())

好的变量和注释并非为计算机而写,而是为每个阅读代码 的人而写(当然也包括你自己)。变量与注释是作者表达思想的基础,是 读者理解代码的第一道门,它们对代码质量的贡献毋庸置疑。

1.1.1 变量常见用法

1
2
3
>>> author = 'piglei'
>>> print('Hello, {}!'.format(author))
Hello, piglei!

java:

1
2
3
String author = "piglei";
String message = String.format("Hello, %s!", author);
System.out.println(message);

Python 是一门动态类型的语言,所以我们无须预先声明变量类 型,直接对变量赋值即可。

也可以在一行语句里同时操作多个变量,比如调换两个变量所指向的值:

1
2
3
4
>>> author, reader = 'piglei', 'raymond'
>>> author, reader = reader, author
>>> author
'raymond'
变量解包

变量解包允许我们 把一个可迭代对象(比如列表)的所有成员,一次性赋值给多个变量:

1
2
3
4
5
6
7
8
9
10
11
12
>>> usernames = ['piglei', 'raymond']
# 注意:左侧变量的个数必须和待展开的列表长度相等,否则会报错
>>> author, reader = usernames
>>> author
'piglei'
#或者:
>>> attrs = [1, ['piglei', 100]]
>>> user_id, (username, score) = attrs
>>> user_id
1
>>> username
'piglei'

只要用星号表达式(*variables)作为变量名,它便会贪婪地捕获多个值对象,并将捕获到的内容作为列表赋值给variables。

1
2
3
4
5
6
7
8
9
>>> data = ['piglei', 'apple', 'orange', 'banana', 100]
>>> username, *fruits, score = data
1
>>> username
'piglei'
>>> fruits
['apple', 'orange', 'banana']
>>> score
100

和常规的切片赋值语句比起来,动态解包语法要直观许多:

1
2
3
4
5
# 1. 动态解包
>>> username, *fruits, score = data
# 2. 切片赋值
>>> username, fruits, score = data[0], data[1:-1], data[-1]
# 两种变量赋值方式完全等价

当然也可以在循环语句中使用:

1
2
3
4
5
>>> for username, score in [['piglei', 100], ['raymond', 60]]:
... print(username)
...
piglei
raymond
单下划线变量名 _

假如你想在解包赋值时忽略某些变量,就可以使用 _ 作为 变量名:

1
2
3
4
# 忽略展开时的第二个变量
>>> author, _ = usernames
# 忽略第一个和最后一个变量之间的所有变量
>>> username, *_, score = data

1.1.2 给变量注明类型

Python 是动态类型语言,使用变量时不需要做任何类型声明。但任何事物都有其两面性。动态类型所带来的缺点是代码的可读性会因此大打折扣。

在 Python 中,函数文档通常称为文档字符串(docstring)。文档字符串是在函数定义中的字符串文字,用于描述函数的目的、用法、参数和返回值等信息。文档字符串通常位于函数定义的第一行下方,用三重引号(单引号或双引号都可以)括起来。

类似这种:

1
2
3
4
5
def remove_invalid(items):
"""剔除 items 里面无效的元素
:param items: 待剔除对象
:type items: 包含整数的列表,[int, ...]
"""

 在上面的函数文档里,我用 :type items: 注明了 items 是个整型列表。任何人只要读到这份文档,马上就能知道参数类型。

当然现在还有类型注解的方式,更加清晰简易:

​ 要使用类型注解,只需在变量后添加类型,并用冒号隔开即可,比如 func(value: str) 表示函数的 value 参数为字符串类型。下面是给 remove_invalid() 函数添加类型注解后的样子:

1
2
3
4
5
from typing import List
def remove_invalid(items: List[int]):
"""剔除 items 里面无效的元素"""
... ...
#List 表示参数为列表类型,[int] 表示里面的成员是整型

1.1.3 变量命名原则

对于普通变量,使用蛇形命名法,比如 max_value; 对于常量,采用全大写字母,使用下划线连接,比如 MAX_VALUE; 如果变量标记为“仅内部使用”,为其增加下划线前缀,比如 _local_var; 当名字与 Python 关键字冲突时,在变量末尾追加下划线,比如 class_。 除变量名以外,PEP 8 中还有许多其他命名规范,比如类名应该使用 驼峰风格(FooClass)、函数应该使用蛇形风格 (bar_function),等等。

数值与字符串

在 Python 里使用整型,你不需要了解“有符号” “无符号”“32 位”“64 位”这些令人头疼的概念。不论多大的数字都能直接用:

1
2
3
4
5
6
# 无符号 64 位整型的最大值(unsigned int64)
>>> 2 ** 64 - 1
18446744073709551615
# 直接乘上 10000 也没问题,永不溢出!
>>> 18446744073709551615 * 10000
184467440737095516150000

和数字一样,Python 里的字符串(string)也很容易上手 。它直接兼容所有的 Unicode 字符:

1
2
3
4
5
6
>>> s = 'Hello, 中文'
>>> type(s)
<class 'str'>
# 打印中文
>>> print(s)
Hello, 中文

2.1.1 数值基础

在 Python 中,一共存在三种内置数值类型:整型(int)、浮点型 (float)和复数类型(complex):

1
2
3
4
5
6
# 定义一个整型
>>> score = 100
# 定义一个浮点型
>>> temp = 37.2
# 定义一个复数
>>> com = 1+2j

int 与 float之间可以通过各自的内置方法进行转换:

1
2
3
4
5
6
# 将浮点数转换为整型
>>> int(temp)
37
# 将整型转换为浮点型
>>> float(score)
100.0

如果数字特别长,可以插入 _ 分隔符:

1
2
3
4
# 以"千"为单位分隔数字
>>> i = 1_000_000
>>> i + 10
1000010

浮点数精度问题:

1
2
>>> 0.1 + 0.2
0.30000000000000004

《Python工匠》读书笔记
http://example.com/2024/04/20/《Python工匠》读书笔记/
作者
notbad3
发布于
2024年4月20日
许可协议