语法小结
1. VSCode 配置
- 安装
python主程序 - 安装
VSCode - 安装插件
python
运行可以有两种方式
- 调试
F5, 或通过菜单中的运行来触发. - 非调试模式运行
Ctrl + F5.
如果在终端运行使用: python <file.py>.
python源文件以.py作为后缀.输出的函数为
python("Hello Python")
个人感觉还是 PyCharm 好用. 不过太重.
提示用户输入 (与 C# 的 Console.ReadLine 对应)
msg = input("提示文字")
- 该方法会阻塞终端, 等待用户输入
- 该方法会在平面上输出提示文字
- 该方法待用户输入数据后 (字符串类型), 会将输入作为返回值返回.
可以使用 int(), float() 等函数将输入的字符进行类型转换.
2. 变量与数据类型
python 是弱类型, 不用声明, 直接使用. 使用等号赋值.
标识符与其他编程语言一样.
- 数字, 字母, 下划线构成
- 不以数字开头
- 大小写敏感
2.1 基本类型
可以使用 type(<var>) 来获得变量类型.
2.2 布尔类型
两个值, True, False.
逻辑运算符: and, or, not. 注意 not 比任何非布尔运算符的优先级都低.
2.3 字符串
- 使用双引号, 单引号括起来.
- 使用
f引号字符串, 可以在字符串中进行插值. 插值语法使用花括号. - 常用的转义字符与
C语言中的一样. 如:'\t','\n'等.
补充
- 三引号字符串可以看成是支持换行的字符串.
- 字符串拼接可以使用
+号.
2.3.1 字符串常用方法
大小写转换 (字符串方法)
<string>.title()<string>.upper()<string>.lower()
注意: 字符串与 C# 中的一样, 是不可变的, 这些修改方法是返回了新字符串.
删除空白方法
<string>.strip()<string>.rstrip()<string>.lstrip()
删除前后缀
实际上就是删除以某某字符开头, 或结尾的内容.
<string>.removeprefix(<beginstr>)<string>.removesuffix(<endstring>)
2.3.2 备注
2.4 数
表示方法:
- 十进制字面量, 支持使用下划线进行分隔数字表达. 例如
1_000_000. - python 默认支持整数, 浮点数, 以及复数.
算术运算: +, -, *, / (浮点除法), // (整除), %, ** (乘幂) 等.
不同于 js 等语言, python 中一些数学方法都以函数的形式提供. 例如: abs(), int(), float() 等.
数字支持位运算. 例如: &, |, ^, <<, >>, 以及 ~ 等.
python 支持批量为变量赋值 (语法比较特殊) x, y, z = 1, 2, 3
python 没有常量, 但约定使用全大写的变量名来表示"常量".
2.5 注释
使用 ## 表示行注释.
3. 复合数据类型
主要介绍列表 list, 元组 tuple, 范围 range, 字典 等.
3.1 列表 list
类似于 js 中的数字, 未约定元素类型的一列数据. 使用方括号括起来, 使用逗号分隔元素.
list = [ 元素, ... ]
列表是 base-0 的, 使用 list[index] 语法来访问元素. 索引支持负数表达, 即从后往前索引.
len(<list>) 获得列表长度.
3.1.1 操作列表
修改元素. 直接使用索引.
删除元素.
del list[<index>], 注意,python不同于js, 后续元素的索引会依次前移. 不会出现稀疏数组.<list>.pop()或<list>.pop(<index>). 不带参数, 默认为0.<list>.remove(<ele>). 删除第一次出现的.
追加元素.
<list>.append(<ele>)<list>.insert(<index>, <ele>)
排序
<list>.sort()对列表排序.sorted(<list>)这是一个函数, 根据列表生成一个排序好的列表. 源列表不变.- 如果需要降序, 添加参数
reverse=True <list>.reverse()是翻转列表方法.
遍历列表
for 迭代变量 in 列表 循环体注意缩进错误.
判断元素在不在列表中使用
in运算符. 表达式结果为 布尔 类型.
3.1.2 切片 slice
语法:
<list>[startIndex:endIndex]
startIndex省略后默认为0.endIndex省略后默认为-1.- 冒号不能省略.
- 索引支持负数.
- 使用
list[:]快速复制数组.
3.2 使用 range 创建数值列表
range 是一个结构, 不是列表, 可用于生成列表用.
基本语法: range(<start>, <end>, [<step> = 1]), 创建一个左闭右开的范围结构.
可以使用函数 list(<range>) 来获得列表.
range 是一个迭代结构, 允许使用 for 直接遍历.
3.2.1 简单统计方法
max()min()sum()count()
逻辑与 SQL 中的聚合函数一样.
3.2.2 列表推导式***
高级货, 好用的东西. 语法:
[迭代表达式 for 迭代变量 in 列表]
逻辑上与 js 中的 map 方法一样.
3.3 元组 tuple
可以视为不可变的列表. 语法是使用圆括号来限定元素.
tuple = (ele, ...)
访问元组的方法与列表相同.
3.4 字典
逻辑上就是 JSON 格式的数据.
- 创建字典,
JSON格式 (key是字符串, 要用引号) - 访问字典成员, 使用
[key]索引. - 添加项, 使用
dic[key] = value, 这个语法也适用于修改字典值. 也可以从空字典开始创建. - 删除字典值, 使用
del dic[key].
读取字典项时, 如果键不存在, 会报错. 可以使用 get() 方法来获取值:
字典.get('键名', '默认值') ## 在键不存在时, 返回默认值
遍历字典:
for key, value in 字典.items():
循环体
- 注意迭代变量
key与value的顺序. - 使用字典的
keys()方法可以遍历字典中的所有键. 还有values()方法. - 默认函数
set()可以利用源创建出不重复的集合来. - 字典, 列表 等复合嵌套使用, 可以构造复杂的数据结构.
4. 流程控制
4.1 分支结构 (if)
if 表达式:
语句
elif 表达式:
语句
else:
语句
- 逻辑运算符:
and,or,not - 关系运算符
>,>=,<,<=,==,!=. - 可以使用圆括号修改优先级.
- 判断在不在列表中使用
ele in list以及ele not in list. - 对于数字
0, 空值None, 空字符串'', 空列表[], 空元组(), 空字典{}都会被识别为False.
4.2 分支结构 (match)
逻辑上就是 switch, 似乎 C# 中的 switch 表达式借鉴了这个吧:
match 变量:
case 常量1: 语句
case ...
_ : 语句
使用 _ 表示默认.
4.3 循环结构
while 表达式:
循环体
跳出循环使用 break, continue. 语法与其他语言一样.
5. 函数
def 函数名(参数列表):
函数体
- 调用使用
函数名(参数列表) - 返回值使用
return
5.1 术语
- 位置实参. 就是平常所说的实参. 只是因为调用时约定了参数顺序, 才被描述成位置实参.
- 关键字实参. 利用
key=value的形式传参. 可以不考虑顺序. 其他语言中具名参数一个意思. - 默认参数. 与其他语言相同. 有默认值的参数就成为了可选参数.
- 引用传递的问题. 列表是引用类型, 传入函数中时, 传入的是引用. 可以借助切片
[:]传入副本.
还是需要明确实参, 形参的含义.
5.2 两个特殊传参
- 元组扩展运算符:
def 函数名(*参数): ...可以传入任意多个参数, 将作为元组传入. - 字典扩展运算符:
def 函数名(**参数): ...可以传入任意多个具名参数, 将作为键值对传入.
例如:
def test1(*list):
for item in list:
print(F"--> {item}")
def test2(**dic):
for k, v in dic.items():
print(F"--> {k} : {v}")
6. 模块 module
- 将函数 (类, 或其他) 定义在文件中(模块).
- 使用
import导入模块 (不需要后缀). - 模块名 (文件名) 就是命名空间.
import 文件名 # 普通导入. 文件名当命名空间使用.
from 文件名 import 函数名 # 导入特定函数, 多个函数用逗号分隔.
from 文件名 import 函数名 as 别名 # 可以为函数取别名.
import 文件名 as 别名 # 为整个模块取别名 (自定义命名空间).
from 文件名 import * # 导入所有成员 (无命名空间, 直接使用, 不推荐).
7. 类语法
7.1 基本用法
定义语法:
class 类名:
def __init__(self, 参数列表):
语句
def 自定义方法(self, 参数):
语句
__init__就是构造函数self就是其他语言中的this, 需要作为第一个参数默认传入. 其他参数不变.- 按照作者描述没有字段一说, 需要什么属性在 构造函数中直接初始化即可 (与
JS的OOP一样). - 适用三引号字符串作为文档注释, 卸载标识符下方.
使用:
instance = 类名([参数])
- 成员也是点出来使用.
- 与其他编程语言不同, 不需要
new关键字.
7.2 继承
基本语法:
class 子类名(父类名):
def __init__(self, 参数, ...):
super().__init__(参数, ...)
其他代码
- 基本逻辑与其他编程语言一样.
- 重写基类方法的方式与
OC相同, 直接实现与父类同名的方法.
7.3 模块
用法与函数的模块用法相同.
8. 标准库
内置库, 书中介绍了 random 模块中的 randint 函数, 以及 choice 函数.
randint生成一个随机整数choice从列表中随机选取一个项
from random import randint, choice
print(randint(1, 6)) # 在 [1, 6] 中生成一个随机数, 注意是闭区间
print(choice([1,2,3,4]))
8.1 文件操作
- 书中介绍了
pathlib模块的Path类. - 该类提供了
read_text()方法, 读取所有的文本内容 (类似于C#中ReadAllText()方法). - 使用换行分隔字符串可以使用
splitlines()方法.
from pathlib import Path
path = Path("文件路径")
lines = path.read_text().splitlines()
写入文件可以使用 write_text()
8.2 异常处理
try:
语句
except 异常名:
异常处理语句
else:
没有异常时会执行这里
然后介绍了 pass 语句. 逻辑上相当于 空语句. 类似于 C 系列中的 {} 语句块语法.
8.3 JSON 序列化
json.loads()
json.dumps()
9. 单元测试
细节可以参考文档.
9.1 基本步骤
使用 pytest 模块. 基本使用步骤:
- 使用
pip安装pytest模块. - 编写测试用的文件, 以及函数 (约定文件名, 函数名使用
test_前缀). - 在函数中使用断言 (
assert). - 执行测试命令
pytest
注意:
pip 相对于 python, 如 npm 相对于 node. pip 会更新比较快. 这里先更新一下:
python -m pip install --upgrade pip
如果是更新某个包
python -m pip install --upgrade 包名
这段命令分为两个部分:
python -m pip表示让python运行pip模块install --upgrade xxx表示更新xxx
注意, linux 中可能不会默认安装
pip.
安装 pytest
python -m pip install --user pytest
表示为当前用户 (--user) 安装 pytest 包.
如果出现问题, 可以去掉
--user再试试.
如果执行 pytest 失败, 可以执行 python -m pytest.
9.2 断言
| 断言 | 用途 |
|---|---|
assert a == b | 断言两个值相等. |
assert a != b | 断言两个值不等. |
assert a | 断言 a 是否为 True |
assert not a | 断言 a 是否为 False |
assert ele in list | 断言 ele 是否在集合 list 中 |
assert ele not in list | 断言 ele 是否不在集合 list 中 |
9.3 夹具 (fixture)
在处理多个单元测试时, 如果需要重复使用某个对象, 可以通过统一的位置创建对象, 在每一个测试函数中引用该对象即可. 这就是夹具.
操作步骤:
- 编写函数, 该函数中创建实例并返回.
- 导入
pytext模块, 并在资源函数上使用模块中的fixture装饰器. - 在测试用例的函数参数中使用资源函数. 用于资源函数同名的变量名作为参数.
- 在测试函数内部直接使用参数作为对应实例.
- 运行测试
import pytest
@python.fixture
def common_data():
...
return ...
def test_demo(common_data):
assert common_data...