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