python - 函数的闭包,迭代器,生成器
一.闭包
1.闭包就是内层函数, 对外层函数(非全局)的变量的引用. 叫闭包
# 闭包
def func():
name = 'alex' # 常驻内存 防止其他程序改变这个变量
def inner():
print(name) # 在内层函数调用了外层函数的变量,叫闭包,可以让一个局部变量常驻内存
return inner
ret = func()
ret() #执行的是inner()
2. __closure__用来检测函数是否闭包. 使用函数名.__closure__
def func():
name = 'alex'
def inner():
print(name)
inner()
print(inner.__closure__) # 是闭包。返回<cell ........>
func()
print(func.__closure__) # 不是闭包,返回None
二.迭代器
1. 可迭代对象 str tuple list set f dict range
2. f 是迭代器
3. 所有的以上数据类型都有一个__iter__()
4. dir()来查看一个对象,数据类型包含了哪些东西
lst = [1,2,3]
#print(dir(lst))
it = lst.__iter__() # 获取迭代器
print("__iter__" in dir(lst)) # 判断是否是一个可迭代的数据类型 iterable
print("__next__" in dir(lst)) # 判断是否是一个迭代器 iterator
print("__iter__" in dir(it))
print("__next__" in dir(it))
# isinstance(对象,类型)
from collections import Iterable
from collections import Iterator
it = lst.__iter__()
print(isinstance(it,Iterable)) # 判断是否可迭代 迭代器一定是可迭代的
print(isinstance(it,Iterator)) # 迭代器里面一定有__next__(),__inter__()
# 模拟for循环
lst = ["鲁班","七号","宫本","武藏"]
it = lst.__iter__()
while True:
try: # 异常处理
name = it.__next__()
print(name , end = ' ')
except StopIteration:
break
5.Iterable: 可迭代对象. 内部包含__iter__()函数
6.terator: 迭代器. 内部包含__iter__() 同时包含__next__().
7.迭代器的特点:
1. 节省内存. 2. 惰性机制 3. 只能往前拿,不能反着拿.
三.生成器
1.生成器实质就是迭代器
2.在python中有三种方式来获取⽣成器:
1. 通过生成器函数 2. 通过各种推导式来实现生成器 3. 通过数据的转换也可以获取⽣成器
3.将函数中的return换成yield就是生成器
# def func():
# print("大家好")
# a = yield '我是练习一年半的个人练习生' # 函数中包含了yield,当前这个函数不再是普通函数,是生成器函数
# print(a)
# b = yield "喜欢篮球"
# print(b)
# c = yield "music" # __next__() 可以让生成器执行下一步
# print(c) # send() 也可以让生成器执行下一步,
# yield "律师函警告" # 给上一个yield传一个值,第一个不能用send(),最后一个不能传值
# g = func() # 获取生成器
# ret = g.__next__()
# print(ret)
# ret2 = g.send("蔡")
# print(ret2)
# ret3 = g.send("rap")
# print(ret3)
# ret4 = g.send("鸡你太美")
# print(ret4)
四.列表推导式
1.列表推导式的常用写法: [ 结果 for 变量 in 可迭代对象]
2.筛选模式: [ 结果 for 变量 in 可迭代对象 if 条件 ]
3.list列表推导式
lst = [i for i in range(4)]
print(lst)
g = (i for i in range(4))
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
4.dict字典推导式
dic = {'a':'b','c':'d'}
dic1 = {dic[i]:i for i in dic}
print(dic1)
5.set集合推导式
lst = ["润田","农夫","润田","山泉"]
s = {i for i in lst}
print(s)
6.寻找名字中带有两个e的人的名字
names = [['Tom',"Billy","Jefferson","Welsey"],
["Alice","Jill","Ana","Weny"]]
lst = [name for first in names for name in first if name.count('e') == 2]
print(lst)
7.生成器表达式和列表推导式的区别:
1. 列表推导式比较耗内存. ⼀次性加载. ⽣成器表达式几乎不占用内存. 使⽤的时候才分配和使用内存
2. 得到的值不⼀样. 列表推导式得到的是⼀个列表. ⽣成器表达式获取的是⼀个生成器.

浙公网安备 33010602011771号