2026.7.17 09:35
学习路线
Python -> Python进阶 -> Python数据分析 -> LangChain -> 机器学习 -> 神经网络 -> NLP -> Coze -> Dify -> 大模型应用基础 -> 大模型微调 -> 多模态 -> vibeCoding
复习巩固总结
一、类
- 类方法 @classmethod
- 静态方法 @staticmethond
- 抽象类 @abstractmethod
三、其他
- 常用内置函数: print abs round pow divmod map filter reduce sorted enumerate zip isinstance issubclass all any ord chr
- 闭包: 函数嵌套、【内层函数】访问【外层函数】的变量、【外层函数】返回【内层函数】
- 装饰器
# 函数-不带参
def say_hello(func):
def wrapper(*args, **kwargs):
# 额外处理
res = func(*args, **kwargs)
# 额外处理
return res
return wrapper
# @say_hello
# 函数-带参
def say_hello(msg):
def outer(func):
def wrapper(*args, **kwargs):
# 额外处理
res = func(*args, **kwargs)
# 额外处理
return res
return wrapper
return outer
# @say_hello('参数')
# 类-不带参
class SayHello:
def __call__(self, func):
def wrapper(*args, **kwargs):
# 额外处理
res = func(*args, **kwargs)
# 额外处理
return res
return wrapper
# @SayHello()
# 类-带参
class SayHello:
def __init__(self, msg):
self.msg = msg
def __call__(self, func):
def wrapper(*args, **kwargs):
# 额外处理
res = func(*args, **kwargs)
# 额外处理
return res
return wrapper
# @SayHello('参数')
Python 学习
122. 变量类型注解
# 变量类型注解: 给变量加上类型说明,可增强代码的可读性、让 IDE 的提示更友好
# num = 100
num: int = 100
num = '你好啊' # 警告
num = [10, 20, 30] # 警告
print(num)
price: float = 12.5
message: str = '你好啊'
num: bool = True
result: None = None # 语法上没有问题,但这么写没有意义
# result = None
# result = 100
# result = 'dfgh'
# result = ()
# 注意: 可以先写变量的类型注解,以后再赋值
school: str # 仅声明变量类型,未创建对象实例
print('************', )
# print('************', school) # 报错
school = '尚硅谷'
# hobby 是列表,并且列表中的所有元素必须是 str 类型
hobby: list[str] = ['抽烟', '喝酒', '烫头']
hobby.append('学习')
# hobby.append(100) # 警告
hobby: list = ['抽烟', '喝酒', '烫头']
hobby.append(10) # 无警告
# hobby = 'fghj' # 警告
# hobby 是列表,并且列表中的元素,可以是: str 或 int 类型
hobby: list[str | int] = ['抽烟', '喝酒', '烫头']
# 上面这行代码的旧写法如下:
# from typing import Union
# hobby:list[Union[str, int]] = ['抽烟', '喝酒', '烫头']
hobby.append('学习')
hobby.append(100)
# hobby.append(12.5) # 警告
# citys 是集合,并且集合中的所有元素必须是 str 类型
citys: set[str] = {'北京', '上海', '深圳'}
citys.add('重庆')
# citys.add(100) # 警告
# citys 是集合,并且集合中的所有元素可以是: str 或 float 或 bool 类型
citys: set[str | float | bool] = {'北京', '上海', '深圳'}
citys.add(12.5)
citys.add('12.5')
citys.add(False)
# persons 是字典,键是 str 类型,值是 int 类型
persons: dict[str, int] = {'张三': 18, '李四': 19, '王五': 20}
persons['李华'] = 21
# persons['李华'] = '21' # 警告
# persons[250] = 21 #
# persons 是字典,键是 str 或 int 类型,值是 int 类型
persons: dict[str | int, int] = {'张三': 18, '李四': 19, '王五': 20}
persons[250] = 21
# 元组的类型声明有点特殊,各位要留意一下:
# scores: tuple[int] = (60, 70, 80) # 报错
# scores 是元组,并且元组中仅包含一个int类型的元素
# scores: tuple[int] = (60) # 报错
scores: tuple[int] = (60,)
# scores 是元组,并且元组中包含三个int类型的元素
scores: tuple[int, int, int] = (60, 70, 80)
# scores 是元组,并且元组中包含任意个数的元素,但每个元素的类型必须是int
scores: tuple[int, ...] = (60, 70, 80)
scores: tuple[int, ...] = (60, 70, 80, 90, 100)
# scores 是元组,并且元组中包含任意个数的元素,每个元素的类型可以是: int 或 str
scores: tuple[int | str, ...] = (60, 70, 80, 90, 100)
scores: tuple[int | str, ...] = (60, '70', 80, '90', 100)
# Python 会根据初始赋值推导变量的类型:
# 1. 对于普通变量: 后续如果改变类型,不会警告
# 2. 对于容器变量: 要求内部元素类型必须与推导出来的一致,否则就会警告
x = 100
x = '尚硅谷'
x: int = 100
# x = '尚硅谷' # 警告
y = [10, 20, 30]
# y.append('40') # 警告
y = 100 # 无警告
y: list[int] = [10, 20, 30]
# y = 100 # 警告
123. 函数类型注解
# 函数类型注解: 给函数的【参数】和【返回值】添加类型说明
# 语法格式: 函数名(参数1: 类型, 参数2: 类型) -> 返回值类型:
# 示例1: 设置参数类型注解、设置返回值类型注解
def add(x, y):
return x + y
def add(x: int, y: int):
return x + y
def add(x: int, y: int) -> int:
return x + y
result = add(10, 20)
print(result)
# result = add(10, '20') # 报错
def add(x: int, y: int) -> int:
# return float(x + y) # 警告
return x + y
# 示例2: 参数有默认值(python可以推导出参数的类型)、设置返回值类型
def add(x=1, y=1) -> int:
return x + y
add(10, 20)
# add(10, '20') # 报错
# 示例3: 设置多个返回值的类型注解
def show_nums_info(nums: list[int]) -> tuple[int, int, float]:
max_value = max(nums)
min_value = min(nums)
result = max_value / min_value
return max_value, min_value, result
result = show_nums_info([10, 20, 30, 40])
print(result)
# 示例4: 设置 *args 的类型注解,要求 args 中的每个参数都必须是 int 类型
def add(*args: int) -> int:
return sum(args)
res = add(10, 20, 30, 40)
print(res)
# 示例5: 设置 **kwargs 的类型注解,要求 kwargs 中的每组参数的值,必须是 str 或 int 类型
def show_info(**kwargs: str | int):
# def show_info(**kwargs: str):
print(kwargs)
show_info(name='张三', age=18, gender='男')
# 获取函数的注解信息
print(add.__annotations__)
124. 错误与异常
# 错误: 代码本身有语法错误,解释器无法执行代码 —— 无法通过异常处理机制解决
# age = 18
# if age >= 18 # 报错
# print('成年人')
# 异常: 代码在语法上没问题,但执行过程中出现了问题 —— 可以通过异常处理机制解决
# 一些开发中常见的异常:
# 1. ZeroDivisionError: 当除数为 0 时触发
# num1 = 100
# num2 = 0
# result = num1 / num2 # 报错
# 2. TypeError: 当操作的数据类型不正确或不兼容时触发
# result = '10' + 5 # 报错
# 3. AttributeError: 当对象没有指定的属性或方法时触发
# 演示1
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p1 = Person('张三', 18)
print(p1.name)
print(p1.age)
# print(p1.gender) # 报错
# 演示2
nums = [10, 20, 30]
nums.append(40)
# nums.add(40) # 报错
# 4. IndexError: 当索引超出范围(索引越界)时触发
nums = [10, 20, 30, 40]
# print(nums[5]) # 报错
# print(nums[4]) # 报错
# 5. NameError: 当使用了不存在的变量时触发
# print(school) # 报错
# 6. KeyError: 当访问字典中不存在的 key 时触发
person = {'name': '张三', 'age': 18}
# print(person['gender']) # 报错
# 7. ValueError: 当值不合法,但类型正确时触发
int('100')
# int('hello') # 报错
# https://docs.python.org/zh-cn/3.13/library/exceptions.html
# BaseException
# ├── BaseExceptionGroup
# ├── GeneratorExit
# ├── KeyboardInterrupt
# ├── SystemExit
# └── Exception ==========================> 开发中常见的异常,基本都是隶属于Exception
# ├── ArithmeticError
# │ ├── FloatingPointError
# │ ├── OverflowError
# │ └── ZeroDivisionError
# ├── AssertionError
# ├── AttributeError
# ├── BufferError
# ├── EOFError
# ├── ExceptionGroup [BaseExceptionGroup]
# ├── ImportError
# │ └── ModuleNotFoundError
# ├── LookupError
# │ ├── IndexError
# │ └── KeyError
# ├── MemoryError
# ├── NameError
# │ └── UnboundLocalError
# ├── OSError
# │ ├── BlockingIOError
# │ ├── ChildProcessError
# │ ├── ConnectionError
# │ │ ├── BrokenPipeError
# │ │ ├── ConnectionAbortedError
# │ │ ├── ConnectionRefusedError
# │ │ └── ConnectionResetError
# │ ├── FileExistsError
# │ ├── FileNotFoundError
# │ ├── InterruptedError
# │ ├── IsADirectoryError
# │ ├── NotADirectoryError
# │ ├── PermissionError
# │ ├── ProcessLookupError
# │ └── TimeoutError
# ├── ReferenceError
# ├── RuntimeError
# │ ├── NotImplementedError
# │ ├── PythonFinalizationError
# │ └── RecursionError
# ├── StopAsyncIteration
# ├── StopIteration
# ├── SyntaxError
# │ └── IndentationError
# │ └── TabError
# ├── SystemError
# ├── TypeError
# ├── ValueError
# │ └── UnicodeError
# │ ├── UnicodeDecodeError
# │ ├── UnicodeEncodeError
# │ └── UnicodeTranslateError
# └── Warning
# ├── BytesWarning
# ├── DeprecationWarning
# ├── EncodingWarning
# ├── FutureWarning
# ├── ImportWarning
# ├── PendingDeprecationWarning
# ├── ResourceWarning
# ├── RuntimeWarning
# ├── SyntaxWarning
# ├── UnicodeWarning
# └── UserWarning
name = input('请输入你的名字') # 直接停止运行 报错 KeyboardInterrupt
2026.07.17 15:10
125. 异常处理
# 【1】 为什么要进行异常处理?
# 程序运行过程中出现的异常,如果得不到处理,那程序就会立即崩溃,导致后续代码无法执行
# 异常处理不是让异常消失,而是将异常捕获到,随后根据异常的具体情况,来执行指定的逻辑
from operator import isub
print('欢迎使用本程序')
a = int(input('请输入第一个数: ')) # 10 hello(ValueError) 10
b = int(input('请输入第二个数: ')) # 2 - 0
result = a / b
print(f'{a}除以{b}的结果是: {result}') # 10除以2的结果是: 5.0 - 报错(ZeroDivisionError)
print('***********我是后续的其他逻辑1***********') # 输出 - -
print('***********我是后续的其他逻辑2***********') # 输出 - -
# 【2】 异常处理(初级)
# 1. 将可能出现异常的代码放在 try 中,出现异常后的处理代码写在 except 中
# 2. 如果 try 中的代码出现异常,那 try 中的后续代码将不会执行,并自动跳转到 except 中处理异常
# 3. 如果 try 中的代码没有异常,那 except 中的代码就不会执行
# 4. 无论是否发生异常,try-except 后面的代码都会继续执行
# 5. 直接写 except 会捕获到 Python 中所有的异常 —— 实际开发中不推荐这样做
print('欢迎使用本程序')
try:
a = int(input('请输入第一个数: ')) # 10 10 hello
b = int(input('请输入第二个数: ')) # 2 0 -
result = a / b
print(f'{a}除以{b}的结果是: {result}') # 10除以2的结果是: 5.0 - -
except:
print('抱歉,程序出现了异常! ') # - 输出 输出
# print(f'{a}除以{b}的结果是: {result}')
print('***********我是后续的其他逻辑1***********') # 输出 输出 输出
print('***********我是后续的其他逻辑2***********') # 输出 输出 输出
# 【3】 异常处理(捕获制定的类型的异常)
print('欢迎使用本程序')
try:
a = int(input('请输入第一个数: ')) # 10 10 hello
b = int(input('请输入第二个数: ')) # 2 0 -
result = a / b
print(f'{a}除以{b}的结果是: {result}') # 10除以2的结果是: 5.0 - -
except ZeroDivisionError:
# print('抱歉,程序出现了异常! ')
print('程序异常: 0不能作为除数! ') # - 输出 -
except ValueError:
print('程序异常: 您输入的必须是数字! ') # - - 输出
print('***********我是后续的其他逻辑1***********') # 输出 输出 输出
print('***********我是后续的其他逻辑2***********') # 输出 输出 输出
# 【4】 验证一下异常类之间的继承关系
# https://docs.python.org/zh-cn/3.13/library/exceptions.html#exception-hierarchy
# issubclass()
print(issubclass(ZeroDivisionError, ArithmeticError)) # True
print(issubclass(ZeroDivisionError, Exception)) # True
print(issubclass(ValueError, Exception)) # True
print(issubclass(KeyboardInterrupt, Exception)) # False
print(issubclass(KeyboardInterrupt, BaseException)) # False
# 【5】 多个 except 从上往下匹配,匹配成功后不再向下匹配
print('欢迎使用本程序')
try:
a = int(input('请输入第一个数: ')) # 10 hello 10
b = int(input('请输入第二个数: ')) # 0 - 2
print(x)
result = a / b
print(f'{a}除以{b}的结果是: {result}')
# except Exception:
# print('程序异常! ') # 打印 打印
except ZeroDivisionError:
print('程序异常: 0不能作为除数! ') # - -
except ValueError:
print('程序异常: 您输入的必须是数字! ') # - -
except Exception:
print('程序异常! ') # 打印
print('***********我是后续的其他逻辑1***********') # 打印 打印
print('***********我是后续的其他逻辑2***********') # 打印 打印
# 【6】 获取异常的具体信息
print('欢迎使用本程序')
try:
a = int(input('请输入第一个数: ')) # 10 hello
b = int(input('请输入第二个数: ')) # 2 -
print(x)
result = a / b
print(f'{a}除以{b}的结果是: {result}')
except ZeroDivisionError:
print('程序异常: 0不能作为除数! ')
# except ValueError:
except ValueError as e:
print('程序异常: 您输入的必须是数字! ')
print(f'⚠️程序异常,异常信息: {e}') # ⚠️程序异常,异常信息: xxx
print(f'⚠️程序异常,异常类型: {type(e)}') # ⚠️程序异常,异常类型: <class 'ValueError'>
print(f'⚠️程序异常,异常参数: {e.args}') # ⚠️程序异常,异常参数: ("xxx",)
print(f'⚠️程序异常,异常的文件: {e.__traceback__.tb_frame.f_code.co_filename}') # ⚠️程序异常,异常的文件: {文件绝对路径}
print(f'⚠️程序异常,异常的具体行数: {e.__traceback__.tb_lineno}') # ⚠️程序异常,异常的具体行数: 79
# except Exception:
# print('程序异常! ')
# except Exception as qwe:
except Exception as e:
# print(f'⚠️程序异常,异常信息: ')
print(f'⚠️程序异常,异常信息: {e}') # ⚠️程序异常,异常信息: name 'x' is not defined
print(f'⚠️程序异常,异常类型: {type(e)}') # ⚠️程序异常,异常类型: <class 'NameError'>
print(f'⚠️程序异常,异常参数: {e.args}') # ⚠️程序异常,异常参数: ("name 'x' is not defined",)
print(f'⚠️程序异常,异常的文件: {e.__traceback__.tb_frame.f_code.co_filename}') # ⚠️程序异常,异常的文件: {文件绝对路径}
print(f'⚠️程序异常,异常的具体行数: {e.__traceback__.tb_lineno}') # ⚠️程序异常,异常的具体行数: 80
# 通过 traceback 来回溯异常
import traceback
# traceback.format_exc()
print(traceback.format_exc())
print('***********我是后续的其他逻辑1***********') # 打印 打印
print('***********我是后续的其他逻辑2***********') # 打印 打印
# 【7】 一个 except,也可以捕获不同的异常
print('欢迎使用本程序')
try:
a = int(input('请输入第一个数: ')) # 10 hello 10 10 10 hello 10
b = int(input('请输入第二个数: ')) # 0 - 2 2 0 - 2
print(x)
result = a / b
print(f'{a}除以{b}的结果是: {result}') # - - - 输出 - - -
# except ZeroDivisionError:
# print('程序异常: 0不能作为除数! ') # 输出 - -
# except ValueError as e:
# print('程序异常: 您输入的必须是数字! ') # - 输出 -
# except Exception as e:
# print(f'程序异常: {e}') # - - 输出
except (ZeroDivisionError, ValueError, Exception) as e:
if isinstance(e, ZeroDivisionError):
print('程序异常: 0不能作为除数! ') # - 输出 - -
elif isinstance(e, ValueError):
int('程序异常: 您输入的必须是数字! ') # - - 输出 -
else:
print(f'程序异常: {e}') # - - - 输出
print('***********我是后续的其他逻辑1***********') # 输出 输出 输出
print('***********我是后续的其他逻辑2***********') # 输出 输出 输出
# 【8】 异常处理的完整写法
# 1. try: 尝试去做可能会出现异常的事情
# 2. except: 出现异常时的处理(出现异常时怎么补救)
# 3. else: 如果一切顺利(没有异常出现)要做的事
# 4. finally: 无论有没有异常,都要做的事
print('欢迎使用本程序')
try:
a = int(input('请输入第一个数: ')) # 10 10 hello
b = int(input('请输入第二个数: ')) # 2 0 -
result = a / b
print(f'{a}除以{b}的结果是: {result}') # 输出 - -
except (ZeroDivisionError, ValueError, Exception) as e:
if isinstance(e, ZeroDivisionError):
print('程序异常: 0不能作为除数! ') # - 输出 -
elif isinstance(e, ValueError):
int('程序异常: 您输入的必须是数字! ') # - - 输出
else:
print(f'程序异常: {e}') # - - -
else:
print('挺好的,try中的代码没有任何异常! ') # 输出 - -
finally:
print('无论有没有异常,我的计算都结束了! ') # 输出 输出 输出
print('***********我是后续的其他逻辑1***********') # 输出 输出 输出
print('***********我是后续的其他逻辑2***********') # 输出 输出 输出
2026.07.17 17:21
126. 手动抛出异常
# 当程序遇到不符合预期情况时,可以使用 raise 语句手动触发(抛出)异常
print('欢迎使用年龄判断系统')
try:
age = int(input('请输入你的年龄: '))
if 18 <= age <= 120:
print('成年')
elif 0 <= age < 18:
print('未成年')
else:
# print('输入的年龄有误(年龄应该为0~120的整数)')
raise ValueError('年龄应该为0~120的整数')
except Exception as e:
# print('我是处理异常的逻辑')
print(f'程序异常: {e}')
# raise NameError('ertghfgfggvb')
raise KeyboardInterrupt('ertghfgfggvb')
2026.07.17 21:04
127. 异常传递机制
# 异常的传递机制:
# 1. 如果异常没有被当前代码块所捕获处理,那该异常就会沿着调用链,逐层传递给其调用者
# 2. 如果所有调用者,都没有捕获该异常,那最终程序将因【未处理异常】而意外终止
def test1():
print('****test1开始****')
# try:
# result = '100' + 100
# except Exception as e:
# print(f'程序异常:{e}')
result = '100' + 100
print('****test1结束****')
def test2():
print('****test2开始****')
try:
test1()
except Exception as e:
print(f'程序异常:{e}')
print('****test2结束****')
def test3():
print('****test3开始****')
test2()
print('****test3结束****')
# test3()
# try:
# test3()
# except Exception as e:
# print(f'程序异常:{e}')
127. 自定义异常类
# 自定义异常类:
# 1. 由开发人员自己定义一个异常类,用来表示代码中“更具体、更有业务含义”的异常
# 2. 具体规则: 定义一个类(类名通常以 Error 结尾),继承 Exception 类或它的子类
class SchoolNameError(Exception):
# pass
def __init__(self, msg):
super().__init__('【校名异常】' + msg)
# raise SchoolNameError('学校名过长')
# raise SchoolNameError('学校名包含敏感词汇')
def check_school_name(name):
if len(name) > 10:
raise SchoolNameError('学校名过长')
else:
print('学校名是合法的')
check_school_name('atguigu')
# check_school_name('atguiguuuuuuuuuuuuuuuu')
try:
check_school_name('atguiguuuuuuuuuuuuuuuu')
except SchoolNameError as e:
print(f'程序异常: {e}')
128. 模块
# order
# 订单最大金额
max_order_amount = 1000000
# 创建订单
def create_order():
print('订单创建成功!')
# 关闭订单
def cancel_order():
print('订单关闭成功!')
# 提示函数
def show_info():
print('我是来自【订单】模块的提示!')
# __all__ = (cancel_order, show_info)
__all__ = ('cancel_order', 'show_info')
# pay
# 支付超时时间
timeout = 1800
# 微信支付
def wechat_pay():
print('我是微信支付!')
# 支付宝支付
def ali_pay():
print('我是支付宝支付!')
# 提示函数
def show_info():
print('我是来自【支付】模块的提示!')
print('我是pay模块打印的内容', __name__)
# 测试代码
# wechat_pay()
# ali_pay()
if __name__ == '__main__':
wechat_pay()
ali_pay()
# main
# 模块概述:
# 1. 在 Python 中,一个.py文件就是一个模块(Module)
# 2. 模块中可以包含: 变量、函数、类、等很多内容
# 3. 通常把能够实现某一特定功能的代码,集中放在一个模块中(模块就类似于一个工具箱)
# 4. 模块可以提高代码的可维护性 与 可复用性,还可以避免命名冲突
# 模块的分类
# Python 中的模块分为三类,分别是: 标准库模块、自定义模块、第三方模块
# 模块命名注意点:
# 1. 要符合标识符命名规则
# 2. 模块名(.py文件名)区分大小写
# 3. 不要与标准库模块同名(一旦同名,Python会优先引入标准库模块)
# 常见的模块导入方式
# 【1】 import 模块名
import order
import pay
from python.python_basic.第10章.order import create_order
print(order.max_order_amount)
order.create_order()
order.cancel_order()
order.show_info()
print('*' * 10)
print(pay.timeout)
pay.wechat_pay()
pay.ali_pay()
pay.show_info()
# 【2】 import 模块名 as 别名
import order as dd
import pay as zf
print(dd.max_order_amount)
dd.create_order()
dd.cancel_order()
dd.show_info()
print('*' * 10)
print(zf.timeout)
zf.wechat_pay()
zf.ali_pay()
zf.show_info()
# 【3】 from 模块名 import 具体内容1, 具体内容2, ......
from order import max_order_amount, show_info
from pay import wechat_pay, ali_pay
print(max_order_amount)
show_info()
wechat_pay()
ali_pay()
# 【4】 from 模块名 import 具体内容1 as 别名1, 具体内容2 as 别名2, ......
from order import max_order_amount as max_amt
from pay import timeout as tm
print(max_amt)
print(tm)
from order import show_info
from pay import show_info
show_info()
from order import show_info as show1
from pay import show_info as show2
show1()
show2()
# 【5】 from 模块名 import *
# max_order_amount = 10
from order import *
max_order_amount = 10
print(max_order_amount)
create_order()
cancel_order()
show_info()
from pay import *
print(timeout)
wechat_pay()
ali_pay()
show_info()
# 关于 __all__:
# 在 Python 模块中,可通过 __all__ 来控制【from 模块 import *】能导入哪些内容
# __all__ 的值可以是: 列表、元组
from order import *
# print(max_order_amount) # 报错
# create_order() # 报错
from order import max_order_amount
print(max_order_amount)
# 关于 __name__:
# __name__是每个 Python 模块(.py文件)都拥有的一个内置变量
# 它的具体值取决于模块的运行方式:
# 1. 作为主程序直接运行,__name__ 的值是 __main__
# 2. 作为模块被导入到其他程序中运行,__name__的模块的文件名(不带.py)
print(__name__)
import pay