Python
邂逅Python
- 概述
- python是一门语法简单、容易上手且应用非常广泛的编程语言,编程语言是人类与计算机之间进行信息交流的一种特殊语言
- python 是动态类型语言,在程序运行时才进行类型检查,变量的类型可以在程序运行过程中改变(一个变量可以接收不同类型的值)
- 终端运行
- 进入语句
- python3 + 回车
- 退出语句
- quit/exit
- 进入语句
数据存储与运算
输入和输出
- 输入
- input()
- 接收的数据默认都是字符串类型
- int(input("请输入年龄:")) # 需要手动转类型
- input()
- 输出
- print()
- print(end='\n') # 结束默认换行,可修改
- print()
字面量和变量
- 字面量
- 程序中直接书写的固定值
- 字面量 = 值本身
- 变量
-
存储数据的容器
-
变量 = 装值的盒子
-
变量名(标识符)的命名规范
- 由数字、字母、下划线组成,且不能以数字开头
- 严格区分大小写
- 不能使用关键字
- 语义化交换
-
交换变量的两种方式
python# 准备数据 a = 10 b = 20 # 方式一:临时变量 temp = a a = b b = temp # 方式二:元组/列表解包 a,b = b,a b,a = [a,b]
-
不可变数据类型
-
int 整数
-
float 浮点数
-
str 字符串
-
bool 布尔
-
布尔类型本质也是整数类型
pythonprint(True == 1) # True print(False == 0) # True
-
-
Nonetype 空值
查看数据类型与类型转换
-
查看数据类型
-
isinstance(变量,类型)
-
看 "所属类型",子类也算,支持继承,判断更准确
python# 查看单个类型 isinstance(变量, int/float/str/bool/tuple/list/dict/set) # 一次判断多个类型 x = 10 isinstance(x, (int, float)) # True 判断是不是 整数 或 浮点数
-
-
type(变量)
- 看 "精确身份",子类不算
-
细节: 变量本身无类型,查看的是变量存储的地址所指向的数据的类型
-
-
数据类型转换
-
int()
python# 能转的: # 纯数字字符串 int("123") # 123 # 浮点数 → 直接砍掉小数(不是四舍五入) int(3.99) # 3 # 布尔值 int(True) # 1 int(False) # 0 # 报错的: # 带字母的字符串 int("abc") # ❌ # 带小数点的字符串 int("3.14") # ❌ -
float()
python# 能转的: # 整数 float(5) # 5.0 # 数字字符串 float("3.14") # 3.14 # 布尔值 float(True) # 1.0 # 报错的: # 非数字字符串 float("abc") # ❌ -
str()
- 任何数据都可以转换成字符串
-
bool()
python# 假 bool(0) → False (数字 0) bool(0.0) → False (浮点数 0.0) bool("") → False (空字符串) bool([]) → False (空列表) bool(()) → False (空元组) bool({}) → False (空字典) bool(set()) → False (空集合) bool(None) → False (None) # 真 bool(1) → True bool(-1) → True bool("hello") → True bool("0") → True (重点:字符串"0"不是0,是True!) bool([0]) → True (列表里有东西,不是空列表,就是True)
-
运算符
-
算术运算符
python+ - * / // % **- / 也称为浮点除法, 改运算符结果一定是浮点数
- // 整数(地板)除法, 结果只保留整数,不看小数
- 算术运算精度丢失
- 出现情景
- 所有浮点数运算都可能出现精度丢失
- 原理
- 因为计算机底层是基于 二进制 进行数据的存储与处理,二进制 无法表示所有的小数,因此涉及到浮点数的计算会精度丢失
- 出现情景
-
赋值运算符
python= += -= *= /= //= %= **= -
比较运算符
python> < >= <= != == -
逻辑运算符
- and
- or
- not
- 配合成员运算符 in 使用
- not in 不存在
- 配合身份运算符 is 使用
- is not 判断对象不是同一个内存地址
- 配合成员运算符 in 使用
-
成员运算符
- in
- not in
-
身份运算符 is(是否是同一内存地址)
pythona = [1,2,3] b = [1,2,3] c = a # is print(a == b) # True 内容一样 print(a is b) # False 但是内存地址不同 print(c is a) # True 指向同一个内存地址 # is not print(a is not b) # True 指向不同内存地址 -
案例
python# 梯形面积 top = float(input("梯形上底:")) bottom = float(input("梯形下底:")) height = float(input('梯形高:')) print(f"梯形的面试是: {(top + bottom) * height / 2}") # 输入圆的半径,计算圆的周长和面积 import math r = float(input("请输入圆的半径:")) perimeter = 2 * math.pi * r area = math.pi * r ** 2 print(f"圆的周长是:{ perimeter },圆的面试是:{ area }") # 身体质量指数BMI的计算 (BMI = 体重(kg) / 身高(m)平方) weight = float(input("请输入您的体重:")) height = float(input("请输入您的身高:")) print(f"您的身体质量指数BMI是:{ weight / height ** 2 }")
数据的逻辑与处理
if条件判断
-
语法
pythonif 条件1: 语句1 elif 条件2: 语句2 else: 以上都不满足时执行 -
案例
python# 判断是平年还是闰年 year = int(input("请输入年份:")) if (year % 400 == 0) or (year % 100 != 0 and year % 4 == 0): print(f"{year} 是闰年") else: print(f"{year} 是平年")python''' 判断三角形,嵌套条件 三角形类型判断:根据输入的三个边的边长(正整数),判断等边三角形、等腰三角形、普通三角形,还是不能构成三角形 1. 构成三角形的条件,任意两边之和大于第三边 2. 三角形判定规则: 三个边都相等是等边三角形 两个边相等是等腰三角形 三个边都不相等是普通三角形 ''' # 1.接收用户输入的a b c a = int(input("请输入三角形的第一个边:")) b = int(input("请输入三角形的第二个边:")) c = int(input("请输入三角形的第三个边:")) if (a + b) > c and (a + c) > b and (b + c) > a: if a == b and b == c: print(f"{a} {b} {c} 三条边构成等边三角形~") elif a == b or a == c or b == c: print(f"{a} {b} {c} 三条边构成等腰三角形~") else: print(f"{a} {b} {c} 三条边构成普通三角形~") else: print(f"{a} {b} {c} 三条边不构成三角形!!!")
模式匹配(重点匹配固定值)
-
语法
pythonmatch 要匹配的变量: case 值1: 代码块 case 值2: 代码块 case _: # 相当于 else,所有其他情况 代码块 -
案例
python# 计算器 num1 = float(input("请输入第一个数:")) num2 = float(input("请输入第二个数:")) oper = input("请输入计算方式+ - * /:") match oper: case "+": print(f"{num1} + {num2} = {num1 + num2}") case "-": print(f"{num1} - {num2} = {num1 - num2}") case "*": print(f"{num1} * {num2} = {num1 * num2}") case "/" if num2 != 0: print(f"{num1} / {num2} = {num1 / num2}") case _: print("操作不支持!!!")
循环
-
while循环
-
理解
- 通过条件表达式来控制是否要进行下一轮循环
-
语法
pythonwhile 条件表达式: 循环体代码 -
注意必须手动更新条件,否则会死循环
-
案例
python# 猜数字 import random random_num = random.randint(1, 100) while True: try: num = int(input("请输入猜测的数字:")) except: print("请输入有效数字!") continue if num > random_num: print("您猜的数字太大了!") continue if num < random_num: print("您猜的数字太小了!") continue print("恭喜你猜对了~") break # 登录 # 定义合法用户(以后加账号直接在这里加,不用改逻辑) USER_LIST = { "admin": "666888", "root": "547527", "zhangsan": "123456" } while True: username = input("请输入用户名:") password = input("请输入密码:") # 判空 if not username or not password: print("用户名和密码不能为空!") continue # 判断是否正确(一行搞定) if username in USER_LIST and USER_LIST[username] == password: print("登陆成功,进入b站首页~") break # 错误提示 print("用户名或密码输入错误,请重新输入!")
-
-
for循环
-
理解
- 本质是一种轮询遍历机制
-
语法
pythonfor 变量 in 可迭代对象: 循环体代码 -
配合range(start, end, step) 函数使用
- 生成指定规则的数字序列
-
嵌套循环案例
python# 99乘法表 for i in range(10): for j in range(1, i+1): print(f'{i} * {j} = { i * j }', end='\t') print() # 打印等腰直角三角形 a = int(input("请输入等腰直角三角形直角边的边长:")) for i in range(1, a+1): for j in range(1, i + 1): print('*', end='\t') print() # 打印国际象棋棋盘 for i in range(1, 9): for j in range(1, 9): if (i + j) % 2 == 0: print("■", end="\t") else: print("□", end="\t") print() # 倒三角 for i in range(5): for j in range(5 - i): print('*', end='') print()
-
-
continue
- 跳过本次循环, 嵌套循环只作用于本层
-
break
- 终止整个循环, 嵌套循环只作用于本层
数据存储容器
数据容器
- 一种可以容纳多份数据的数据类型,容纳的每一份数据称之为一个元素, 每一个元素都可以是任意类型的数据,如字符串、数字、布尔等
不可变类型
不能增删改的,改内容,地址改变
int、float、str、bool、tuple
整数
浮点数
布尔
字符串
-
定义与创建
- 单引号
- 双引号
- 三引号,支持换行,长文本
-
特点
- 有序、不可变、可迭代性 、可重复
-
转义符与原始字符串
- 单个反斜杠转义符 \
- \n 换行符
- \t 制表符(相当于按 Tab 键)
- r 不想转义,可以用原始字符串,开头加 r
- print(r"D:\test\a.txt")
-
字符串拼接
-
'+' 加号拼接, 遇到非字符串使用 str() 方法进行类型转换
pythonname = "小李" age = 20 print("姓名:" + name + ",年龄:" + str(age)) -
f"内容{变量/表达式}"
pythonname = "小李" age = 20 height = 1.73 print(f"姓名:{name},年龄:{age - 1}, 身高: { height: .2f }") -
% 占位符写法
-
%s 字符串站位
pythontitle = '大白菜' print('蔬菜%s' % title) -
%d 整数站位
- 书写时会校验类型,如果是字符串报错,如果是浮点数只保留整数位
pythontotal = 7 print('总价%d元' % total) -
%f 浮点数站位
-
书写时会校验类型,如果是字符串会报错,如果是整数展示成浮点数添0
-
细节: %m.nf 表示浮点数的宽度为m位包含小数点, 保留n位小数
python# 整个数字是5位数 包含小数点, 保留2位小数 price = 19.99print('价格为%5.2f' % price)
-
-
-
-
下标与切片
-
下标
python# 正向索引 'hello'[0] # 'h' # 反向索引 'hello'[-1] # 'o' -
切片
-
语法
- 开始索引:结束索引:步长 开始索引默认为0,结束索引默认为容器长度,步长默认为1
-
几种情况
python# 不写起始, 从头开始 s[:4] # 从0到4 # 不写结束, 到尾结束 s[2:] # 从2到最后 # 步长为 -1 → 字符串反转 s[::-1] # 复制整个字符串 s[:]
-
-
-
常用方法/函数
- sub in str - 判断是否存在
- isinstance(变量, str) - 判断变量是否是字符串类型
- len(str) - 查看字符串的长度
- str.find(sub) / str.rfind(sub) / str.index(sub)
-
find 找第一次出现的位置
python# 字符串.find(sub, 开始位置, 结束位置) # 左→右 s = "abcabc" print(s.find("abc")) # 0 👈 从左往右找,第一次出现 -
rfind 找最后一次出现的位置
python# 字符串.rfind(sub, 开始位置, 结束位置) # 右→左 s = "abcabc" print(s.rfind("abc")) # 3 👈 从右往左找,最后一次出现 -
find和rfind共同点
- 都返回索引下标
- 找不到都返回 -1
- 都可以指定 start 和 end
-
查看子串在总串的中第一次出现的下标,不存在报错
-
- str.count(sub)
- 统计子串在总串中出现的次数,没有是0次
- str.replace(被替换的字符串,新字符串)
- 字符串替换
- 不会修改原字符串,必须用新变量接收结果
- 找不到要替换的内容,不会报错,直接返回原字符串
- str.isdigit()
- 判断字符串是不是「纯数字」,是就返回 True,不是就返回 False
- str.split(分割符)
- 按照分割符分割字符串,返回一个列表对象(不修改原字符串)
- str.strip(sub)
- 如果不传参数,去除字符串前后空格; 如果传参了,按照字符串一个一个移除字符串前后的,注意只移除前后的中间的不会去除,返回新的字符串(不修改原字符串)
- str.startswith(sub)
- 判断字符串是否以什么字符开头
- str.endswith("n")
- 判断字符串是否以什么字符结尾
- str.upper() / str.lower()
- 全部大写/全部小写
- 分隔符字符串.join(列表/元组/字符串等) 有局限性慎用
-
join 只认这 3 种东西
- 纯字符串列表
- 纯字符串元组
- 字符串本身
- 里面只要混了 int /float/bool / None / 对象 → 直接报错!
-
示例
pythonlst = ["苹果", "香蕉", "橙子"] res = ",".join(lst) # 输出:苹果,香蕉,橙子# 空格分隔 print(" ".join(lst)) # 苹果 香蕉 橙子# 横线分隔 print("-".join(lst)) # 苹果-香蕉-橙子# 无分隔(直接连在一起) print("".join(lst)) # 苹果香蕉橙子
-
-
扩展
- Unicode码
- 是一套全球通用的字符编码标准,简单说就是给世界上所有的文字、符号都编个唯一的"身份证号",让电脑能统一识别和处理,彻底解决不同语言间的乱码问题
- ASCII 只是 Unicode 的子集
- 查看字符的码点/根据码点查看字符
- 字符转数字(根据单个字符获取unicode编码码点)
- ord('a') / ord('你')
- ord - ordinal(序号)
- 数字转字符(根据unicode编码码点获取对应的字符)
- chr(97)
- chr - character(字符)
- 字符转数字(根据单个字符获取unicode编码码点)
- Unicode码
元组
- 空元组定义
- t = ()
- t = tuple()
- t = (5,) 和 t = (5)
- 注意: t = (5) # ❌ 这是整数 5
- t = (5,) # 这才是元组
- 只有一个元素的元组,必须加逗号!
- 特点
- 有序、不可变、可迭代性 、可重复(支持存储不同类型)
- 可存储任意类型
- 元组不存数据本身,只存内存地址。所有类型的地址格式都一样。所以元组可以存任意类型。
- 常用方法/函数
- 元素 in 元组 - 元素是否在元组中
- isinstance(变量, tuple) - 查看变量是否是元组类型
- len(元组) - 查看元组的长度
- t.index(元素) - 查找元素在元组中的索引,不存在报错
- t.count(元素) - 统计元素在元组中的个数
- 索引/切片
- 同字符串和列表
- 元组不能修改、删除、添加元素,只能查看 / 切片
- 组包和解包
- 组包
- 将多个值合并到一个容器(元组、列表)中
- t2 = (1,2,3,4) # 元组组包
- 解包
- 将容器(元组、列表)解开成独立的元素,分别赋值给多个变量
- a,b,c,d = t2 # 1,2,3,4
- a, *b, d = t2 # 1,2,3,4
- a, *b = t2 # 1, 2,3,4
- *a, b = t2 # 1,2,3,4
- 组包
- 元组没有推导式
- (i for i in range(5)) # 这是生成器
可变类型
能增删改的,直接改内容,地址不变
list、dict、set
列表
-
定义
- l = \[\]
- l = list()
-
特点
- 有序、可修改、可重复、有索引
-
列表推导式
- l = i for i in range(5)
-
可存任意类型
- 列表不存数据本身,只存内存地址。所有类型的地址格式都一样。所以列表可以存任意类型。
-
索引/切片 同元组、字符串
-
方法
-
元素 in 列表 - 查看元素是否在列表中
-
isinstance(变量, list) - 查看元素是否是列表类型
-
查看
pythonlen(列表) #列表的长度 列表.count(元素) # 统计元素出现次数,不修改原列表,返回值:整数(次数) 列表.index(元素) # 获取元素第一次出现的索引,不修改原列表,返回值:整数(索引),找不到报错 max(列表)/min(列表)/sum(列表) # 列表最大值、最小值、总和 -
删除
python列表.clear() # 列表清空,修改原列表(变空) del 列表[索引] # 删除指定索引元素,修改原列表 列表.remove(元素) # 删除第一个匹配元素,修改原列表 列表.pop(索引)/pop() # 删除指定索引 / 默认删最后一个,修改原列表,返回删除元素 -
修改
python列表.extend(列表) # 批量追加元素(展开添加),修改原列表 列表.append(单个元素/列表) # 尾部添加一个元素,传列表会把列表当一个整体加进去,修改原列表 列表.insert(索引,元素) # 在指定索引前面插入元素,修改原列表 列表.reverse() # 反转列表,修改原列表 reversed(列表/元组/字符串) # 反转列表,不修改原列表,不直接返回列表,返回的是一个迭代器;迭代器就是专门给 for 循环遍历用的,不能下标访问,不能打印,只能 for 循环遍历 -
排序
python列表.sort() # 原地排序(默认升序),修改原列表 sorted(列表) # 不修改原列表,返回新列表
-
-
解包和组包
pythonnum_list1 = [1,2,3,4,5,6] num_list2 = [1,2,3,4,5,6] num_list = [*num_list1, *num_list2] -
扩展
- enumerate = 遍历列表 / 可迭代对象时,同时拿到 索引 + 元素
-
注意
- 列表不能一边遍历一边删除,删除需要拷贝一份
-
集合
-
定义空集合
- set()
- 注意不能是{},这是空字典
-
特点
-
无序、可修改、不可重复、存任意不可变类型的数据
-
查找快: dict /set 底层 = 哈希表, 查找 = 直接算地址,不遍历,时间复杂度 O (1),速度不受数据量影响
-
无序示例
pythonmy_set = {"苹果", "香蕉", "橙子"} print(my_set) # 多次打印存储内容顺序会变 -
集合推导式
- s = {x for i in range(5)}
-
-
方法
-
元素 in 集合 - 元素是否在集合中
-
len(集合) - 查看集合的长度
-
会修改原集合
pythonadd(元素) # 添加一个元素,已存在则不报错、不添加 remove(元素) # 删除指定元素,元素不存在 报错(KeyError) pop() # 随机删除一个元素,并返回它。如果集合是空的 报错 a.update(b) # 把 b 的所有元素添加到 a 中,自动去重 a.difference_update(b) # 在 a 里,去掉 a 和 b 的交集 s.clear() # 清空集合,变成空集合 -
不会修改原集合,返回新集合
pythona.difference(b) 或 - # 差集:a 有、b 没有,返回新集合,不修改 a 和 b # 案例 方式一: print("选修了足球但没有选修篮球:", football_set.difference(basketball_set)) # 方式二: print("选修了足球但没有选修篮球:", football_set - basketball_set) # 方式三: print("选修了足球但没有选修篮球:", {item for item in football_set if item not in basketball_set}) a.intersection(b) 或 & # 交集:a 和 b 都有的元素,✅ 返回新集合 # 案例 方式一: print("同时选修的法语和艺术:", french_set.intersection(art_set)) # 方式二: print("同时选修的法语和艺术:", french_set & art_set) a.union(b) 或 | # 并集:所有元素,自动去重,✅ 返回新集合案例 # 方式一: all_set = football_set | basketball_set | french_set | art_set # 方式二: all_list = { *football_set, *basketball_set, *french_set, *art_set }
-
字典
- 概述
- 使用键值对来存储数据,每一个键都对应一个值,根据键可以快速找到值
- 空字典
- d = {}
- d = dict()
- 特点
- 有序(3.7+)、可修改、不可重复
- 查找快: dict /set 底层 = 哈希表, 查找 = 直接算地址,不遍历,时间复杂度 O (1),速度不受数据量影响
- 存储不同类型数据
- 字典推导式
- d = { x: x**2 for i in range(5) }
- 方法
-
查询
pythonkey in 字典 # 判断key是否在字典中 len() # 统计字典内键值对总数 字典.keys() # 返回所有键,类型为 dict_keys(可迭代对象) 字典.values() # 获取字典里所有的值(value),返回一个可迭代的视图对象 字典.items() # 返回所有键值对元组,类型为 dict_items # 细节字典[key],根据键取值,键不存在直接报错 -
删除
python字典.pop(key) # 删除指定键的键值对,返回被删除的 value;键不存在报错 del 字典[key] # 直接删除指定键值对,无返回值;键不存在报错 字典.clear() # 清空所有键值对,字典变为空字典 {} -
修改
python字典[key] = value # 键已存在:覆盖原有值,实现修改 / 键不存在:新增一组键值对
-
可变类型的深拷贝和浅拷贝
python
# 浅拷贝
列表/字典/集合 .copy()
# 深拷贝
import copy
copy.deepcopy(列表/字典)
# 注意:集合不涉及深拷贝,因为集合不能存可变类型
集合、列表、元组对比
- 存储区别
- 它们都能存任意类型,能力几乎一样
- 列表:可存任意类型
- 元组:可存任意类型
- 集合:可存任意不可变类型
- 特点区别
- 列表(三可):有序、可改、可重复
- 元组(一不可):有序、不可改、可重复
- 集合(两不可):无序、 可改、不可重复(自动去重)
序列
- 概述
- 序列是指:内容连续、有序,可使用下标索引的一类数据容器
- 列表、元组、字符串,均可以视为序列
- 序列起始:结束:步长
- 起始可以省略,省略从头开始
- 结束可以省略,省略到尾结束
- 步长可以省略,省略步长为1(可以为负数,表示倒叙执行)
数据类型转换
- list() - 转列表(有序、可改)
- set() - 转集合(去重、无序)
- tuple() - 转元组(有序、不可改)
- str() - 转字符串
函数
概述
- 组织好的、可重复使用的、实现特定功能的代码片段
作用域
-
变量的作用域是指变量的作用范围
-
函数内部定义的是局部变量,外部定义的变量是全局变量
pythonif / for / while → 不产生局部变量 def(函数) → 产生局部变量 class(类) → 产生类属性 -
生命周期区别
- 全局变量,全程序可见,程序运行全程存活。修改不可变类型需 global,可变类型直接改
- 局部变量,仅函数内可见,函数运行时创建、结束即销毁,外部无法访问
-
修改方式区别
python不可变全局变量(数字 / 字符串): 要修改 → 必须加 global 不加 → 不影响外面 可变全局变量(列表 / 字典 / 集合): 修改内部内容 → 不用 global 会直接影响外面! 局部变量随便改
参数
- 位置参数
- 调用函数时根据函数定义的参数位置来传递参数
- 传递的参数和定义的参数的顺序和个数必须一致
- 关键字参数
- 函数调用时通过 "键=值" 形式传递参数
- 注意: 函数调用时,如果有位置参数,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序
- 默认值参数
- 在函数定义的时候,提供默认值
- 注意:函数调用时,如果为缺省参数传值则修改默认参数值,否则用这个默认值
- 不定长参数
-
位置不定长参数(*args)
-
函数定义参数变成了*args,传进的所有参数都会被args变量收集,它会根据参数的位置合并成一个元组,args是元组类型
-
示例
python# 可变位置参数 def my_print(*args): print(args) # 位置传参 my_print('小名', 20, '男') # 将这三个参数打包成元组,args = ('小名', 20, '男')
-
-
关键字不定长参数(**kwargs)
-
函数定义参数变成了**kwargs,参数是"键 = 值"形式的情况下,所有的"键 = 值"都会被kwargs接受,同时会根据"键 = 值"组成字典,kwargs是字典类型
-
示例
pythondef sum(*args, **kwargs): total = 0 for num in args: total += num for k,v in kwargs.items(): total += v return total data_dict = { 'a': 100, 'b': 100, 'c': 100} data_tuple = (100,200,300) res = sum(*data_tuple, **data_dict)print(res)
-
-
元组拆包和列表拆包和字典拆包
pythont = (1,2,3) l = [1,2,3] d = {'a':1, 'b': 2} print(*t) print(*l) print(**d) # print 不支持这种打印
-
lambda表达式(匿名函数)
- 语法
- lambda 形参1,形参2,... : 单行表达式 或 函数调用
- 细节
- 不用写return,没有参数可以不写,也可以不返回结果只打印
- 有判断条件的表达式
- max_str = lambda a,b: max((a,b), key=len) if len(a) != len(b) else 'a' + '\n' + 'b'
类型注解
python
# 类型注解 会有类型推断
i:int = 10
f:float = 0.1
s:str = "hello-python"
b:bool = True
n:None = None
l:list[str|int|float] = ["1","2",2,1.1]
st:set[int] = {1,2,3}
t:tuple[str, int, float] = ("苹果", 10, 30.1)
d:dict[str,int] = {"a":1}
递归函数
- 递归条件
- 函数内部自己调用自己
- 要有终止条件
- 案例
python
# 求阶乘
def recursive_fun(n):
if n == 1:
return 1
return n * recursive_fun(n - 1)
# 汉诺塔
def han_nuo_ta(n, A, B, C):
if n == 1:
print(f"将{n}盘从【{A}】盘移动到【{C}】盘")
return
# 把上方n-1个盘子从A借助C移动到B
han_nuo_ta(n-1, A, C, B)
# 将A移动到C
print(f"将{n}盘从【{A}】盘移动到【{C}】盘")
# 将n-1从B借助A移动到C
han_nuo_ta(n-1, B, A, C)
# 斐波那契数列
def fun(n):
if n == 1:
return 0
if n == 2:
return 1
return fun(n-1) + fun(n-2)
异常处理
语法
python
try:
# 【可能会出错的代码】放在这里
正常执行的代码块
except 异常类型1:
# 【捕获指定异常】出错时执行
处理异常1的代码
except 异常类型2:
# 捕获另一种异常
处理异常2的代码
except Exception as e:
# 【捕获所有其他异常】万能捕获
print("捕获到异常:", e)
else:
# 【没有异常】才会执行
程序正常时执行的代码
finally:
# 【无论是否异常,最终一定执行】
必须执行的代码(如关闭文件、释放资源)
3条规则
- try 必须搭配 except 或 finally
- except 可以写多个,精准捕获不同错误
- finally 最常用:关闭文件、关闭数据库、释放锁
文件操作
打开
python
# with 语法:
# 确保资源总是被正确获取和释放,即使发生异常,也会被正确释放
# 不需要close 自动关闭 不会丢数据 不会报错
# 打开
with open("文件路径", "打开模式", encoding="utf-8") as 变量名:
# 读/写操作
读
python
# 一次性读全部
with open("test.txt", "r", encoding="utf-8") as f:
content = f.read()
print(content)
# 按行读(最常用)
with open("test.txt", "r", encoding="utf-8") as f:
for line in f:
print(line.strip()) # 去掉换行
# 一次性读所有行,方便遍历
with open("test.txt", "r", encoding="utf-8") as f:
lines = [line.strip() for line in f.readlines()]
写
python
# 写
with open("test.txt", "w", encoding="utf-8") as f:
f.write("第一行内容\n")
f.write("第二行内容\n")
# 追加
with open("test.txt", "a", encoding="utf-8") as f:
f.write("追加一行\n")
# 读写一起用
with open("test.txt", "r+", encoding="utf-8") as f:
content = f.read()
f.write("新增内容\n")
关
python
f.close()
打开模式
- r
- 只读(默认)
- 文件不存在报错
- 不覆盖
- w
- 只写(覆盖)
- 文件不存在创建
- 覆盖
- a
- 追加写
- 文件不存在创建
- 不覆盖
- r+
- 读写
- 文件不存在报错
- 不覆盖
- w+
- 读写
- 文件不存在创建
- 覆盖
- a+
- 追加读写
- 文件不存在创建
- 不覆盖
模块
导入方式
python
# 导入整个模块
import random
# 从模块里导入指定功能
from random import randint, choice
# 从模块里导入全部内容
from random import *
# 导入时起别名
import random as rd
# 自定义模块
from 自定义模块名 import 函数名
__all__ = [] # 规定外部可使用的函数
# from 模块名 import * __all__ = []只能控制这种导入方式
# from 模块名 import 函数名 __all__ = []这种导入方式控制不住
# import 模块名 __all__ = []通过模块名调用也控制不住
常用模块
-
系统 / 文件操作
python# 操作系统交互:路径、文件夹、文件、执行系统命令 import os # 操作文件 os.rename(目标文件名称,新文件名称) 对文件进行重命名操作 os.remove(要删除文件名称) 对文件进行删除操作 os.path.exists(文件路径) # 操作文件夹 os.mkdir(文件路径):创建一个指定名称的文件夹 os.getcwd():current work directory,获取当前目录名称 os.chdir(切换后目录名称):change directory,切换目录 os.listdir(目标目录):获取指定目录下的文件信息,返回列表 os.rmdir(目标目录):用于删除一个指定名称的'空'文件夹 shutil.rmtree():删除非空目录 # 环境变量 os.environ 获取所有环境变量 -
随机数模块
python# 生成随机数、随机选择、打乱序列 import random random.randint(1,10) # 随机整数 [1,10] random.choice([1,2,3]) # 随机选一个元素 -
时间 / 日期模块
python# 时间戳、延时 import time time.time() # 时间戳 毫秒 浮点数 time.sleep(2) # 暂停2秒 当前时间、日期格式化(比 time 更易用) from datetime import datetime print(datetime.now()) # 当前时间 now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") # 格式化当前时间 print(now) -
textwrap
python# 把一长串文字,按照你指定的最大宽度,切成一个「字符串列表」 import textwraps = "我是一段很长很长的文本,需要自动换行显示" lines = textwrap.wrap(s, 5) # 核心用法 输出列表
包
-
包含
python__init__.py文件 -
导入方式
pythonfrom 包名 import * # 受限__init__.py文件中的 __all__ = []
模块和包的区别
- 模块 = 一个 .py 文件
- 包 = 一个包含 init.py 的文件夹