jk's notes
  • 语法小结

语法小结

VSCode 配置

  1. 安装 python 主程序
  2. 安装 VSCode
  3. 安装插件 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

  1. 将函数 (类, 或其他) 定义在文件中(模块).
  2. 使用 import 导入模块 (不需要后缀).
  3. 模块名 (文件名) 就是命名空间.
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 模块. 基本使用步骤:

  1. 使用 pip 安装 pytest 模块.
  2. 编写测试用的文件, 以及函数 (约定文件名, 函数名使用 test_ 前缀).
  3. 在函数中使用断言 (assert).
  4. 执行测试命令 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)

在处理多个单元测试时, 如果需要重复使用某个对象, 可以通过统一的位置创建对象, 在每一个测试函数中引用该对象即可. 这就是夹具.

操作步骤:

  1. 编写函数, 该函数中创建实例并返回.
  2. 导入 pytext 模块, 并在资源函数上使用模块中的 fixture 装饰器.
  3. 在测试用例的函数参数中使用资源函数. 用于资源函数同名的变量名作为参数.
  4. 在测试函数内部直接使用参数作为对应实例.
  5. 运行测试
import pytest

@python.fixture
def common_data():
  ...
  return ...

def test_demo(common_data):
  assert common_data...
Last Updated:
Contributors: jk