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. 得到的值不⼀样. 列表推导式得到的是⼀个列表. ⽣成器表达式获取的是⼀个生成器. 

 

posted @ 2019-07-04 16:15  书,生  阅读(451)  评论(0)    收藏  举报