2026.7.20 13:06
学习路线
rust
Python -> Python进阶 -> Python数据分析 -> LangChain -> 机器学习 -> 神经网络 -> NLP -> Coze -> Dify -> 大模型应用基础 -> 大模型微调 -> 多模态 -> vibeCoding
复习巩固总结
一、装饰器
python
# 函数-不带参
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
import xxx as x -> x.func()
from xxx import func as fc -> fc()
from xxx import * -> fc()
__all__
- 在 Python 模块中,可通过
__all__来控制【from 模块 import *】能导入哪些内容 __all__的值可以是: 列表、元组
__name__
- 作为主程序直接运行,
__name__的值是__main__ - 作为模块被导入到其他程序中运行,
__name__的模块的文件名(不带.py) - 可以用于模块测试 三、包
- 引入包
python
import pack.moudule -> pack.moudule.xxx
import pack.moudule as xx -> xx.xxx
from pack.moudule import func -> func()
from pack.moudule import func as fc -> fc()
from pack.moudule import * -> func()
from pack import moudule -> module.xxx
from pack import moudule as md -> md.xxx
from pack import * -> moudule.xxx
import pack -> pack.moudule.xxx
- 第三方包
- pyCharm 左下角打开终端执行 pip install
- pyCharm 右下角点击当前项目名称,点击解释器设置,点击加号搜索增加
Python 学习
132. 初识迭代器
python
# 知识点1: 能被 for 循环遍历的对象,被称为: 可迭代对象(iterable)
# region
names = ['张三', '李四', '王五']
citys = ('北京', '上海', '深圳')
msg = 'hello'
age = 10
def test():
pass
for item in names:
print(item)
for item in citys:
print(item)
for item in msg:
print(item)
# for item in age: # 报错
# print(item)
# for item in test: # 报错
# print(item)
# endregion
# 知识点2: 可迭代对象(iterable)能调用到 __iter__ 方法
# region
names = ['张三', '李四', '王五']
citys = ('北京', '上海', '深圳')
msg = 'hello'
age = 10
def test():
pass
names.__iter__()
citys.__iter__()
msg.__iter__()
# age.__iter__() # 报错
# test.__iter__() # 报错
print(hasattr(names, '__iter__')) # True
print(hasattr(citys, '__iter__')) # True
print(hasattr(msg, '__iter__')) # True
print(hasattr(age, '__iter__')) # False
print(hasattr(test, '__iter__')) # False
# endregion
# 知识点3: 调用 __iter__ 方法会得到: 迭代器(iterator)
# 备注1: __iter__ 是一个魔法方法,当调用 iter 函数时,__iter__ 会自动调用
# 备注2: 可迭代对象.__iter__() 等价于 iter(可迭代对象)
# 备注3: 如果 iter(obj) 能得到一个迭代器(iterator),那 obj 就是可迭代对象
# region
names = ['张三', '李四', '王五']
citys = ('北京', '上海', '深圳')
msg = 'hello'
print(names.__iter__())
print(citys.__iter__())
print(msg.__iter__())
print(iter(names))
print(iter(citys))
print(iter(msg))
# endregion
# 知识点4: 迭代器(iterator)拥有 __next__ 方法,每次调用都会根据当前的状态,返回下一个元素
# 备注1: 迭代器.__next__() 等价于 next(迭代器)
# 备注2: 当所有元素全都取出后,若继续调用 __next__ 方法,Python会抛出 StopIteration 异常
# region
names = ['张三', '李四', '王五']
# iter(names)
# names.__iter__()
it = iter(names)
print(it.__next__()) # 张三
print(it.__next__()) # 李四
print(it.__next__()) # 王五
# print(it.__next__()) # 报错
# print(next(it)) # 张三
# print(next(it)) # 李四
# print(next(it)) # 王五
# print(next(it)) # 报错
# endregion
# for循环背后的工作逻辑
# region
names = ['张三', '李四', '王五']
# 编写for循环遍历names列表
for item in names:
print(item)
# for循环背后的逻辑
# 【1】 调用【可迭代对象的 __iter__ 方法】获取到一个迭代器(iterator)
it = iter(names)
# 【2】 开启一个无限循环
while True:
try:
# 【3】 调用 __next__ 方法,获取下一个元素
item = next(it)
print(item)
except StopIteration:
# 【4】 捕获 StopIteration 异常,随后结束循环
break
# endregion
# 知识点5: 迭代器(iterator)也拥有 __iter__ 方法,并且其返回值是迭代器自身
# 这么设计的原因如下: 让 for 循环也能遍历迭代器(即: 为了让 iter(迭代器) 不出错)
names = ['张三', '李四', '王五']
it = iter(names)
print(it) # 地址1
# it.__iter__()
result = iter(it)
print(result) # 地址1
print(it == result) # True
x = iter(result)
print(x) # 地址1
names = ['张三', '李四', '王五']
it = iter(names)
print(it)
for item in it:
print(item)
# 知识点6: 迭代器协议
# 1. 能被 iter() 接受
# 2. 能被 next() 一步一步取值
133. 手写迭代器
python
# 迭代器是一次性的,状态只会向前推进,且不会自动重置(迭代器在遍历的过程中会被"消耗")
# region
names = ['张三', '李四', '王五']
it = iter(names)
print(next(it)) # 张三
print(next(it)) # 李四
print(next(it)) # 王五
# print(next(it)) # 报错
# print(next(it))
# print(next(it))
it1 = iter(names)
print(next(it1))
print(next(it1))
print(next(it1))
print(it) # 地址1
print(it1) # 地址2
for item in names:
print(item)
for item in names:
print(item)
it = iter(names)
for item in it:
print(item)
# 打印空
for item in it:
print(item)
for item in it1:
print(item)
# endregion
# 需求: 让 for 循环可以遍历 Person 的实例对象
# 实现方式【1】
# region
class Person:
def __init__(self, name, age, gender, address):
self.name = name
self.age = age
self.gender = gender
self.address = address
def __iter__(self):
# return 迭代器
# return PersonIterator()
# return PersonIterator(p1)
return PersonIterator(self)
# return PersonIterator(100)
# 目标:
p1 = Person('张三', 18, '男', '昌平')
# for item in p1: # 报错
# print(item)
class PersonIterator:
# def __init__(self, num):
def __init__(self, p):
# 将外部传进来的数据保存好
self.p = p
# 设置迭代器的初始化状态(指针位置)
self.index = 0
# 配置好要遍历的内容
# self.attrs = [p.name, p.age]
self.attrs = [p.name, p.age, p.gender, p.address]
# 迭代器的 __iter__ 方法会返回迭代器自身
def __iter__(self):
# pass
return self
# 每次调用 __next__ 方法,会根据当前的状态,返回下一个元素
def __next__(self):
# pass
# 如果指针的位置超出范围,那就抛出 StopIteration 异常
if self.index >= len(self.attrs):
raise StopIteration
# 获取要返回的内容
value = self.attrs[self.index]
# 更新迭代器状态(指针位置)
self.index += 1
# 返回value
return value
p1 = Person('张三', 18, '男', '昌平')
for item in p1:
print(item)
for item in p1:
print(item)
it = iter(p1)
for item in it:
print(item)
# 空输出
for item in it:
print(item)
# endregion
# 实现方式【2】
# region
class Person:
def __init__(self, name, age, gender, address):
self.name = name
self.age = age
self.gender = gender
self.address = address
# 设置迭代器的初始化状态(指针位置)
self.__index = 0
# 配置好要遍历的内容
self.__attrs = [name, age, gender, address]
def __iter__(self):
# return 迭代器类()
self.__index = 0
return self
def __next__(self):
# 如果指针的位置超出范围,那就抛出 StopIteration 异常
if self.__index >= len(self.__attrs):
raise StopIteration
# 获取要返回的内容
value = self.__attrs[self.__index]
# 更新迭代器状态(指针位置)
self.__index += 1
# 返回value
return value
# 目标:
# 下面的p1既是可迭代对象,又是迭代器
p1 = Person('张三', 18, '男', '昌平')
for item in p1: # 报错 -> 无
print(item)
# 无打印 -> 打印
for item in p1:
print(item)
# 无打印 -> 打印
for item in p1:
print(item)
it = iter(p1)
# 打印
for item in it:
print(item)
# 打印
for item in it:
print(item)
# endregion
# 进阶: 迭代器玩的就是 __next__
from cn2an import an2cn
class Person:
def __init__(self, name, age, gender, address):
self.name = name
self.age = age
self.gender = gender
self.address = address
# 设置迭代器的初始化状态(指针位置)
self.__index = 0
# 配置好要遍历的内容
self.__attrs = [name, age, gender, address]
def __iter__(self):
# return 迭代器类()
self.__index = 0
return self
def __next__(self):
# 如果指针的位置超出范围,那就抛出 StopIteration 异常
if self.__index >= len(self.__attrs):
raise StopIteration
# 获取要返回的内容
value = self.__attrs[self.__index]
# 将字符串转为大写
if isinstance(value, str): # 不加报错
value = value.upper()
# 将数字转汉语形式
if isinstance(value, int):
value = an2cn(value)
# 更新迭代器状态(指针位置)
self.__index += 1
# 返回value
return value
# 目标:
# 下面的p1既是可迭代对象,又是迭代器
p1 = Person('zhangsan', 18, '男', '昌平')
2026.07.20 20:16
134. 迭代器的优势
python
# 1. 迭代器是惰性计算,不会一次性生成所有结果,所以能显著降低内存占用
# 2. 当数据量很大,不确定要用多少结果时候,推荐使用迭代器
import tracemalloc
# 使用迭代器实现
class Fibo:
def __init__(self, total):
# 要生成多少个数
self.total = total
# 当前生成到第几个了(计数器,指针)
self.index = 0
# 初始的两个值
self.pre = 1
self.cur = 1
def __iter__(self):
return self
def __next__(self):
# 当生成足够数量后,抛出 StopIteration 异常
if self.index >= self.total:
raise StopIteration
# 前两项都是1
if self.index < 2:
value = 1
else:
# 新的结果等于前两项的和
value = self.pre + self.cur
# 更新一下pre和cur
self.pre = self.cur
self.cur = value
# 计数器+1
self.index += 1
# 返回value
return value
# 看内存占用
tracemalloc.start()
# f1 = Fibo(10)
# f1 = Fibo(100)
# f1 = Fibo(1000)
# f1 = Fibo(10000)
f1 = Fibo(100000)
m = tracemalloc.get_traced_memory()[1]
print(f'内存占用是: {m / 1024 / 1024}MB')
# print(f1)
for item in f1:
print(item)
# 不用迭代器实现
def fibo(total):
if total <= 0:
return []
if total == 1:
return [1]
nums = [1, 1]
for i in range (2, total):
nums.append(nums[-1] + nums[-2])
return nums
tracemalloc.start()
# f2 = fibo(10)
# f2 = fibo(10000)
f2 = fibo(100000)
m = tracemalloc.get_traced_memory()[1]
print(f'内存占用是: {m / 1024 / 1024}MB')
print(f2)
for item in f2:
print(item)
f1 = Fibo(100000)
for n in f1:
if n > 100:
break
print(n)
f1 = fibo(100000)
for n in f1:
if n > 100:
break
print(n)
135. 生成器
python
# 【1】 生成器:
# 1. 生成器函数: 函数体中如果出现了 yield 关键字,那该函数是【生成器函数】
# 2. 生成器对象: 调用【生成器函数】时,其函数体不会立即执行,而是返回一个【生成器对象】
# 备注: 不管能否执行到 yield 所在的位置,只要函数中有 yield 关键字,那该函数,就是【生成器函数】
# region
from python.test01.demo import result
def demo():
print('demo函数开始执行了')
print(100)
a = 200
print(a)
demo()
def demo():
print('demo函数开始执行了')
print(100)
yield
a = 200
print(a)
d = demo()
def demo():
print('demo函数开始执行了')
print(100)
if 1 == 0:
yield
a = 200
print(a)
d = demo()
# endregion
# 【2】 写在【生成器函数】中的代码,需要通过【生成器对象】来执行
# 1. 调用【生成器对象】的 __next__ 方法,会让【生成器函数】中的代码开始执行
# 2. 当【生成器函数】中的代码开始执行后,遇到 yield 会"暂停"执行,并且其内部会记录"暂停"的位置
# 3. 后续调用 __next__ 方法时,都会从上一次"暂停"的位置,继续运行,直到再次遇到 yield
# 4. 遇到 return 会抛出 StopIteration 异常,并将 return 后面的表达式,作为异常信息
# 5. yield 后面所写的表达式,会作为本次 __next__ 方法的返回值
# region
def demo():
print('demo函数开始执行了')
print(100)
# yield
yield '我是第1个yield所返回的数据'
a = 200
print(a)
yield '我是第1个yield所返回的数据'
b = 300
print(b)
return '尚硅谷'
d = demo()
# print(d)
# d.__next__()
# result = next(d)
# print(result) # None -> 我是第1个yield所返回的数据
r1 = next(d)
print(r1) # 我是第1个yield所返回的数据
# next(d)
r2 = next(d)
print(r2) # 我是第2个yield所返回的数据
# r3 = next(d) # 报错
# print(r3)
try:
next(d)
except StopIteration as e:
print(e)
# endregion
# 【3】 生成器对象是一种特殊的迭代器(本质是通过 yield 自动实现了迭代器协议)
# region
def demo():
print('demo函数开始执行了')
print(100)
yield '我是第1个yield所返回的数据'
a = 200
print(a)
yield '我是第1个yield所返回的数据'
b = 300
print(b)
return '尚硅谷'
d = demo()
# 验证: 生成器对象d,和迭代器一样,也拥有: __iter__ 和 __next__ 方法
print(hasattr(d, '__iter__')) # True
print(hasattr(d, '__next__')) # True
# 验证: 生成器对象的 __iter__ 方法,和迭代器一样,返回的也是自身
result = iter(d)
print(result == d)
# for循环遍历生成器
for item in d:
print(item)
# for循环背后的逻辑
gen = iter(d)
while True:
try:
value = next(gen)
print(value)
except StopIteration:
break
# endregion
# 【4】 yield 也能写在循环里
# region
def create_car(total):
# for index in range(total):
for index in range(1, total + 1):
# yield f'我是第{index + 1}台车'
yield f'我是第{index}台车'
# cars是生成器对象
cars = create_car(5)
print(cars)
# 调用一次cars的 __next__ 方法,就会得到一台车
c1 = next(cars)
print(c1)
c2 = next(cars)
print(c2)
c3 = next(cars)
print(c3)
c4 = next(cars)
print(c4)
c5 = next(cars)
print(c5)
# c6 = next(cars) # 报错
# print(c6)
for car in cars:
print(car)
# endregion
# 【5】 yield from 能把一个【可迭代对象】里的东西依次 yield 出去(代替: for + yield)
# region
def demo():
nums = [10, 20, 30, 40]
yield from nums
# for n in nums:
# yield n
d = demo()
r1 = next(d)
print(r1)
r2 = next(d)
print(r2)
r3 = next(d)
print(r3)
r4 = next(d)
print(r4)
for item in d:
print(item)
# endregion
# 【6】 使用: 生成器.send(值)可以让生成器继续执行的同时,给上一次 yield 传值
# 备注1: next 只能取值,send 既能取值,也能送值
# 备注2: 第一次启动生成器,不能传值!
# region
def demo():
print('demo函数开始执行了')
print(100)
a = yield '我是第1个yield所返回的数据'
print(a)
b = yield '我是第1个yield所返回的数据'
print(b)
return '尚硅谷'
d = demo()
r1 = next(d) # 相当于 r1 = d.send(None)
# r1 = d.send(333) # 报错
print(r1)
# r2 = next(d)
# print(r2)
r2 = d.send(666)
print(r2)
# r3 = d.send(888)
# print(r3)
# d.send(888)
try:
d.send(888)
except StopIteration as e:
print(e)
# endregion
# 用生成器实现遍历Person类的实例对象
# region
class Person:
def __init__(self, name, age, gender, address):
self.name = name
self.age = age
self.gender = gender
self.address = address
self.__attr = [name, age, gender, address]
def __iter__(self):
# yield self.name
# yield self.age
# yield self.gender
# yield self.address
yield from self.__attr
p1 = Person('张三', 18, '男', '北京昌平')
# 目标:
# for attr in p1: # 报错
# print(attr)
# endregion
# 用生成器实现斐波那契数列
# region
def fibo(total):
pre = 1
cur = 1
for index in range(total):
if index < 2:
yield 1
else:
value = pre + cur
pre = cur
cur = value
yield value
f1 = fibo(10)
print(f1)
for item in f1:
print(item)
# 无论是迭代器,还是生成器对象,都可以用list、tuple、set等直接拿到其里面的所有内容(注意: 容易挤爆内存)
result = list(f1)
print(result)
result = tuple(f1)
print(result)
result = set(f1)
print(result)
# endregion
# 生成器表达式: 一种用类似列表推导式的语法,快速创建生成器对象的方式
# 语法格式: (表达式 for 变量 in 可迭代对象)
# 什么时候适合用生成器表达式?------ 当"每个结果,只依赖当前这一个元素"时
nums = [10, 20, 30, 40]
# 列表推导式
result = [n * 2 for n in nums]
print(result)
# 生成器表达式
result1 = (n * 2 for n in nums)
print(result1)
x = list(result1)
print(x)
for item in result1:
print(item)