Python三大器:装饰器、迭代器、生成器
dir()
- 查看对象的属性和方法:对于任何给定的Python对象或类,
dir()
可以帮助你快速了解它有哪些可用的属性和方法。这对于学习新的库或框架时特别有用,可以快速了解对象提供了哪些功能。 - 调试和探索:当你在探索一个新的或不熟悉的Python对象时,
dir()
可以帮助你发现可以调用的方法或者可以访问的属性,这对于调试和理解对象的内部结构非常有帮助。 - 交互式使用:在Python的交互式环境中(如Python shell或Jupyter notebook),
dir()
是探索对象的快捷方式之一。它可以让你快速看到一个对象的“目录”,从而探索其功能。 - 反射编程:
dir()
函数也可以用于反射编程(introspection programming),即代码能够检查并动态地访问其他模块或函数的属性。这在动态加载模块或者动态调用方法时非常有用。
# 示例:使用dir()查看列表的方法
my_list = [1, 2, 3]
print(dir(my_list))
# 输出示例(输出会根据Python版本有所不同,以下为示例输出):
# ['__add__', '__class__', '__contains__', '__delattr__', ..., 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'...]
迭代器(Iterators)
迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。迭代器有两个基本的方法:iter() 和 next()。字符串、列表或元组对象都可用于创建迭代器:
my_list = [1, 2, 3, 4]
my_iter = iter(my_list)
print(next(my_iter)) # 输出 1
print(next(my_iter)) # 输出 2
- for 循环内部大致的工作机制
lst = ['张无忌', '谢广坤', '张晨晨']
it = lst.__iter__()
while True:
try:
obj = it.__next__()
prit(obj)
except StopIteration:
break
# for循环
for item in lst:
print(item)
迭代器总结
- Iterable:可迭代对象,内部宝行
__iter__()
函数 - Iterator:迭代器,内部包含
__iter__()
同时包含__next__()
- 迭代器的特点:
- 节省内存
- 惰性机制
- 不能反复,只能向下执行(即无法后退)
生成器(Generators)
def func():
print(123)
yield "你好"
- 当函数中有yield,该函数就是一个生成器函数,yield也有返回的意思
- 生成器函数在被执行时,实际上是创建一个生成器出来
生成器函数.__next__()
可以让生成器函数执行到下一个yield结束- 当后面没有yield之后,再次
__next__()
会报错StopIteration - 深坑:要值的时候才拿值(惰性机制-生成器本质上就是迭代器)
def func():
print(11)
yeild "你好"
print(22)
yeild "你不好"
print(33)
yeild "你很好"
gen = func() # 此时控制台没有打印
r = gen.__next__()
print(r) # 控制台打印:11\n你好
r2 = gen.__next__()
print(r2) # 控制台打印:22\n你不好
r3 = gen.__next__()
print(r3) # 控制台打印:33\n你很好
生成器最大作用就是节省内存
def order():
lst = []
for i in range(10000):
lst.append(f'衣服{i}')
return lst # 列表占内存
lst = order()
print(lst)
def order():
for i in range(10000):
yield f'衣服{i}'
g = order()
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
def order():
lst = []
for i in range(10000):
lst.append(f'衣服{i}')
if len(lst) == 50:
yield lst
lst = []
g = order()
print(g.__next__()) # 衣服0~衣服49
print(g.__next__()) # 衣服50~衣服99
send()
- 与
__next__
异同- 相同点:可以执行到下一个yield
- 不同点:send可以给上一个yield位置传值
- 第一次执行必须用next,不能用send
def func():
print("111")
a = yield "酥饼"
print("222", a)
b = yield "韭菜盒子"
print("333", b)
yield "红酒"
g = func()
r1 = g.__next__()
print(r1)
r2 = g.send("哈哈哈") # send给上一个yield位置传递“哈哈哈”
print(r2)
# 打印结果
# 111
# 酥饼
# 222 哈哈哈
# 韭菜盒子
各种推导式
- 列表推导式的基本语法: [结果 for循环 if 条件]
# 常规写法
lst = []
for i in range(1, 11):
lst.append(i)
print(lst)
# 推导式写法
lst = [i for i in range(1,11)]
## 把1-10中所有奇数添加到列表
lst = [i for i in range(1, 11) if i %2 == 1]
## 把1-10中所有奇数的平方添加到列表
lst = [i**2 for i in range(1,11) if i % 2 == 1]
## python x 1 ~ python x 255
lst = ["python x %s" % i for i in range(1, 256)]
- 字典推导式的基本语法:{key: value for循环 if条件}
lst = ['你好', '你不好', '你很好']
d = {i: lst[i] for i in range(len(lst))}
- 集合推导式的基本语法:{key for循环 if条件}
lst = ['张无忌', '张三丰', '周芷若']
s = {item for item in lst}
Python中没有元组推导式
- 生成器推导式的基本语法:(结果 for循环 if条件)
g = (i for i in range(5))
print(g)
print(g.__next__())
print(g.__next__())
print(g.__next__())
- 拿空生成器中的数据
#直接for循环
g = (i for i in range(5))
print(g)
for item in g:
print(item)
# 可以使用list、tuple、set
g = (i for i in range(5))
print(g)
print(list(g)) # tuple(g)、set(g)
匿名函数
- 语法:函数名 = lambda 参数: 返回值
为了解决一些简单的需求而设计的一句话函数
# 计算n的n次方:
def func(n):
return n**n
print(func(10))
# 匿名函数实现
f = lambda n: n**n
print(f(10))
- 函数的参数可以有多个,多个参数之间用逗号隔开
- 匿名函数不管多复杂,只能写一行,且逻辑结束后直接返回数据
- 返回值和正常函数一样,可以是任意数据类型
- 匿名函数并不是说一定没有名字,这里前面的变量就是一个函数名,说他是匿名函数原因是我们通过
__name__
查看的时候是没有名字的,统一都叫lambda,在调用的时候没有什么特别之处,像正常函数调用即可