ch01 起步
1. 编程环境简介与安装
主要说明不同系统中 python 存在一定差异. 本章重点是安装.
本书基于 python3.11
的版本, 理论上 python3.9+
的版本都可以运行书中的代码.
可以在终端尝试运行 python, 演示了本书如何展示代码, 其中 >>>
是命令提示符.
本书采用 VSCode
作为编辑器. 本书附录 B 介绍了一些其他的编辑器.
然后介绍在各个操作系统中安装 python (win, macOS, Linux).
- win 安装注意, 在安装向导过程中, 添加到环境变量.
在终端打印 python
即可看到是否安装成功:
安装 VSCode
, 以及 python
扩展 (在扩展中搜索, 选择 Microsoft 的扩展).
2. 运行 Hello World 程序
步骤:
在桌面创建文件夹
python_work
. 用于放置项目 (建议字符使用小写字母, 下划线代替空格).使用
VSCode
开发文件夹, 创建hello_python.py
文件.编写代码:
print("Hello Python World!")
运行程序, 选择菜单栏 Run > Run Without Debugging 或 Ctrl + F5.
具体用法可以参考附录 B.
注意:
- 如果没有安装
python
扩展, 直接Ctrl+ F5
会提示安装扩展.Ctrl + F5
是只运行, 不调试.F5
是运行 + 调试.
然后作者介绍了上述程序如果运行失败可能存在的问题 (略).
3. 在终端运行 python
使用命令:
python <python 文件>.py
需要注意在 Linux 和 macOS 中
python
命令时指python2
, 应该使用python3
命令.即
python3 <python 文件>.py
.
ch02 变量和简单的数据类型
1. 运行 hello_world.py 时发生的情况
运行 .py
文件时, 后缀名 .py
表示它是一个 python 程序, 因此会使用 python 解释器来读取整个文件, 然后解析它, 最后再执行.
在解析的过程汇总, 解释器会知道代码中有什么变量, 使用了什么函数. 使用编辑器的时候也会有语法高亮, 这个功能也是对代码进行词法解析得到的.
2. 变量
变量的语法: 直接使用标识符 = 值
即可.
message = 'Hello PythonWorld!'
message
为变量名, 不需要var
等关键词引导声明字符串使用单引号, 双引号均可
不需要分号结尾
变量的值可以随时修改, 再使用 (逻辑上, 无类型)
2.1 变量的命名与使用
组成:
- 字母, 数字, 下划线组成. 不能以数字开头.
- 不允许包含空格.
- 勿使用关键词或函数名作为变量名.
- 慎用
1
,l
,0
,O
等字符. 变量名应简明, 命名应见名得义.
py3 支持中文变量名, 但不推荐.
变量名大小写敏感, 但一般大写字母有特定用法, 变量名使用小写为宜.
2.2 避免命名错误
如果编写出现错误, 解释器会给出报错.
话说 IDE 也可以
2.3 变量是标签
对变量的一个白话解释性描述.
3. 字符串
字符串 (string) 是一系列字符. 在 py 中使用单引号, 或双引号括起来的都是字符串.
这个可以在字符串中嵌入引号. 例如 "I'm a student" 等
3.1 大小写
针对英文内容字符串
.title()
方法. 将每个单词首字母大写, 其余字符小写. 返回新字符串, 不会对源字符串修改.
.upper()
方法. 全大写.
.lower()
方法. 全小写.
3.2 在字符串中使用变量
就是插值. 使用语法: f
来引导字符串. 使用花括号来插值. 例如:
message = f"abc{ variable }"
3.3 使用空白
用来对齐, 布局. 常用的如 空格, 制表符 (\t
), 换行符 (\n
) 等.
3.4 删除空白
返回新字符串, 并非对源字符串修改. 可将修改结果赋值回源字符串来实现修改.
.strip()
. 去除两端空白..rstrip()
. 去除右边空白..lstrip()
. 去除左边空白.
3.5 删除前缀
.removeprefix()
. 删除字符串前缀.
4. 数
数字类型支持使用 _
作为分隔符使用. 例如: 1_000_000
4.1 整数
运算: +
, -
, *
,/
(小数除法), **
(乘幂).
优先级与数学中一致. 使用括号调整优先级.
4.2 浮点数
带有小数点的数字是浮点数
需要注意的是: 0.1 + 0.2
不等于 0.3
本书第二部分会介绍如何处理多余小数位
4.3 整数与浮点数
说的是隐式类型转换. 略.
4.4 数中的下划线
一个语法糖, 在数字表示时易于阅读, 但底层存储忽略下划线.
组合数字的时候, 一般会从右向左三个一组 (整数部分).
4.5 同时为多个变量赋值
类似于 js 总解耦的语法:
x, y, z = 1, 2, 3
4.6 常量
Python 没有常量的语法, 但一般采用全大写形式的名字来描述常量.
例如: MAC_CONNECTIONS = 5000
.
5. 注释
单行注释: ##
6. Python 之禅 (约定与思想, 略)
代码要简洁.
ch03 列表简介
简单来说就是数组, 集合, 这类线性数据类型.
1. 列表是什么
列表 list 就是一列元素, py 并没有约定每一个元素的类型必须一致.
语法:
list = [ 元素, 元素, ... ]
- 使用方括号界定列表
- 使用逗号分隔元素
打印列表的时候, 会以内部格式打印, 包括方括号.
1.1 访问元素
使用 [index]
索引来访问元素.
注意索引从 0
开始.
如果使用负数作为索引, 是从后往前检索元素. -1
表示最后一个.
逻辑上
-n
就是length - n
.
2. 修改, 添加和删除元素
2.1 修改元素
使用下标访问, 直接赋值.
2.2 添加元素
追加使用 .append()
方法.
插入元素使用 .insert(index, elem)
方法.
2.3 删除元素
- 使用
del
语法删除. 语法与 JS 一样.del list[index]
.
不同的是, 删除不同于 JS 会变成稀疏数组, 后续的元素索引会自动前移
pop()
方法也可以弹出一个元素 (注意从结尾处弹出).pop()
可以带有索引参数, 表示删除对应位置的元素 (pop
可以看成是removeAtIndex
).- 还有一个
remove
方法, 根据等值判断删除第一个出现的元素, 如果元素不存在会报错.
3. 列表管理
简单来说就是操作数组, 涉及到排序
.sort()
方法, 永久排序. 默认按字母排序, 如果带有参数reverse=True
则采用降序.sorted()
函数会根据数组生成一个新的排序好的数组, 源数组不变. 也可以传入reverse
参数.- 翻转数组
.reverse()
. len()
获取数组长度.
4. 避免索引使用错误
- 超出索引范围
ch04 操作列表
遍历列表:
for 迭代变量 in 列表:
循环体
注意, python 使用索引来表达层级.
书中相关小结: 深入研究循环, 是对循环语法的解释; 在 for 中执行更多, 相当于解释使用代码块来表示循环体, 来执行多个语句; 而在 for 循环后执行, 是说在循环结束后需要移除缩进.
一个习惯是在循环结束后加一个空行.
注意 for 循环体中是允许有空行的.
避免缩进的错误
多缩进, 少缩进.
遗漏冒号.
3. 创建数值列表
之前都是字符串列表, 这里介绍数值列表.
range(left, right)
函数. 创建一个左闭右开的整数区间集合.range()
允许第三个参数, 用于表示步长 (相当于默认为 1). 可用来构造等差数列.
借助于 range
可以创建出任意的数值列表. 例如构建等差数列:
_base = range(1, 10)
arr = []
for n in _base:
arr.append(n * 2)
需要注意的是
range
生成的不是列表, 可以理解为是一个结构.jk: 初步理解为一个延迟执行的结构, 表示的是一个列表的结构.
jk: 新版的内容与旧版的内容有些不同, 将
range
转换为列表, 可以使用list()
函数
简单统计
max()
min()
sum()
列表推导式*
很好用. 很好用. 很好用.
[使用迭代变量的表达式 for 迭代变量 in 基列表]
如创建等差数列
[v * 2 for v in range(1, 11)]
再如计算函数 f()
的映射可以写成
[f(v) for v in range(1, 11)]
4. 使用列表的一部分
4.1 切片 (slice)
语法:
列表[startIndex:endIndex]
切片返回的就是列表.
startIndex
可省略, 默认为 0, 注意冒号不能省略. 也支持负数索引.endIndex
可省略. 默认为全部.使用
[:]
可以复制列表 (列表可以理解为引用类型, 不能直接使用变量赋值得到).
5. 元组 (tuple)
列表是可变的, 元组是不可变的.
t = (item1, item2, ...)
列表使用方括号, 元组使用圆括号.
访问元素单个索引位置的元素, 语法与 列表一样. 使用
[index]
注意, 元素是由 逗号分隔的, 括号只是为了好识别, 若单个元素的元组需要写成
(3,)
元组遍历与列表相同.
6. 设置代码格式 (规范, 略)
缩进 4 空格,
行长 80 字符.
注意使用空行, 有助于理解代码.
ch05 if 语句
语法:
if 表达式:
语句
elif 表达式:
语句
else:
语句
逻辑运算符: and
, or
, 使用圆括号可以修改优先级.
关系运算符: >
, >=
, <
, <=
, ==
, !=
.
判断是否在列表中: v in list
与 v not in list
.
对于 数值
0
, 空值None
, 空字符串''
或""
, 空列表[]
, 空元组()
, 空字典{}
, 都会被识别为False
.
然后用一个案例, 解释了两个列表交集运算的应用.
ch06 字典
逻辑上就是 JSON
格式的数据.
- 创建字典,
JSON
格式 (key
是字符串, 要用引号) - 访问字典成员, 使用
[key]
索引. - 添加项, 使用
dic[key] = value
, 这个语法也适用于修改字典值. 也可以从空字典开始创建. - 删除字典值, 使用
del dic[key]
.
读取字典项时, 如果键不存在, 会报错. 可以使用 get()
方法来获取值:
字典.get('键名', '默认值') ## 在键不存在时, 返回默认值
遍历字典:
for key, value in 字典.items():
循环体
使用字典的 keys()
方法可以遍历字典中的所有键. 还有 values()
方法.
默认函数 set()
可以利用源创建出不重复的集合来.
嵌套
列表项为字典的情况, 或其他. 就是构造复杂数据类型.
ch07 用户输入和 while 循环
1. input()
- 该方法会阻塞终端, 等待用户输入
- 该方法会在平面上输出提示文字
- 该方法待用户输入数据后 (字符串类型), 会将输入作为返回值返回.
msg = input('提示文字')
使用 \n
, \t
等格式化提示文字.
使用 int()
函数可以将字符串转换为数字.
求模运算符 %
2. while 循环
while 表达式:
语句
然后讨论了怎么来控制表达式让用户输入某些数据后结束循环.
然后介绍了 break
关键字, 跳出循环.
介绍 continue
关键字, 进入下一轮循环.
注意: 避免死循环
3. 使用 while 处理列表和字典
for
循环基于索引, 不应该在 for
循环中对列表进行有关索引变更的操作.
可以考虑使用 while
循环.
介绍了两个案例:
- 循环变量列表中的元素, 将列表中的元素一个个移动到另一个列表中.
- 循环删除列表中的某一个值的元素 (默认
remove()
只会删除第一个).
while 循环条件如果是列表, 当列表中没有元素时也判定为
False
判断列表中是否含有某个元素, 可以使用
元素 in 列表
来判断.
使用字典. 字典的逻辑与 JSON 一样.
dic = {} ## 创建字典
dic[key] = value ## 存储键值对
使用 for in
循环遍历字典
for k, v in dic.items():
## 使用 k 表示键, 使用 v 表示对应的值
注意迭代变量的顺序
ch08 函数
定义函数语法:
def 函数名():
函数体
调用语法:
函数名()
介绍了文档字符串, 使用三引号, 它是一个块级注释.
然后介绍了传参, 实参形参的概念.
- 位置实参. 就是按照定义的参数顺序依次传入参数 (无新, 只是引入新概念).
- 关键字实参. 即为命名参数, 利用
name=value
的形式传参, 可以不考虑顺序.
然后介绍了参数 默认值.
函数返回值也使用 return 值
.
可先参数 (可以使用默认值来使得参数可选, 置空字符串, if
可判断)
空字符串作为 判断条件, 被认定为
False
然后介绍如何在函数中返回字典.
然后介绍将列表作为参数传入函数. 并介绍在函数内对列表元素进行修改 (引用传递的问题).
然后介绍阻止在函数内对列表进行修改 (使用 [:]
传入列表的副本, 修改也没用).
最后作者提到了, 少用函数副本, 会有性能问题.
然后介绍传入任意个数的位置实参. 在参数名前使用星号, 在函数中将其作为元组使用.
def 函数名(*参数名):
函数体
逻辑上就是
c##
的params
, 或js
中的...
然后介绍任意数量的关键字实参. 使用两个前置星号. 那么参数就成了字典类型.
def 函数名(**参数):
函数体
将函数存储在模块中
导入模块的语法
导入使用 import
语法导入整个模块.
import 文件名
文件名作为模块名, 不需要后缀.
所谓模块就是包含代码的
py
文件. (似乎没有什么特殊的语法来限制访问).
导入后, 模块名作为命名空间使用.
导入特定函数
语法:
from 模块名 import 函数名
如果有多个函数, 用逗号分隔.
使用 as 为函数取别名
from 模块名 import 函数名 as 别名
使用 as 为模块取别名
import 模块名 as 别名
导入模块中的所有函数
from 模块名 import *
直接使用函数名即可. 没有命名空间. 但不建议, 有命名冲突的风险.
函数编写指南 (略)
介绍一些函数编码习惯与约定