Python生成器、迭代器、闭包、装饰器的学习

1.生成器

1.什么是生成器

什么是生成器呢.
简单来讲就是在你准备输出内容时又不想将全部内容输出,使用生成器可以将输出的内容储存为一个地址,等到需要的时候可以再对内容接着输出,若输出内容为多个的话则使用一次生成器执行一次内容.

2.创建生成器的方式

它与列表解析式有点相像:
# 列表解析式
list1 = [x for x in range(3)]
print(list1) # [0, 1, 2]

# 一.
# 创建生成器第一种方式
# 此处调用次数为3次,超出则报错
list1 = (x for x in range(3)) # 将列表解析式的[]改成()
# <generator object <genexpr> at 0x00F79568>
print(list1)
print(next(list1)) # 0
print(next(list1)) # 1 
print(next(list1)) # 2
list1 = ("hello" for i in range(3))
# <generator object <genexpr> at 0x00F90D10>
print(list1)
print(next(list1)) # hello
print(next(list1)) # hello
print(next(list1)) # hello

# 二.
# 使用yield方法
# 只要函数中含有 yield 这个关键字,这个函数就变成了生成器
# 需求1、1、2、3、5、8、13、21、34、……后一个数为前两个数之和
# 定义一个函数
def createNum():
    print("__1__")
    a, b = 0, 1
    for i in range(3):
        print("__2__")
        yield b
        print("__3__")
        a, b = b, a + b
        print("__4__")

# 定义一个变量
num = createNum()
# 因为该定义函数又yield方法,所以是一个生成器,生成器将输出数据储存为地址,需要调用才对其进行输出
print(num) # <generator object createNum at 0x01E91D10>
# 使用next()方法或者变量.__next__()方法调用
print(next(num))
"""
__1__
__2__
1 执行到yield b 时停止运行
"""
print(num.__next__()) # 再次调用才往下执行循环到yield b 停止
"""
__3__
__4__
__2__
1
"""

另外可以用send()方法进行传值👇

# 定义一个函数
def createNum():
    for i in range(5):
        r = yield i
        print(r)

a = createNum()
# print(next(a))
# print(next(a))
# print(next(a))
# print(next(a))
# print(next(a))
# 正常调用执行
"""
其中调用函数中yield i没有传值默认为None
0
None
1
None
2
None
3
None
4
"""
# 使用send()给yield i整体传值
# can't send non-None value to a just-started generator 无法将非 None 值发送到刚启动的生成器
a.send(None)
a.send("hello")
a.send("world")
print(next(a))
print(next(a))
"""
第一次传值
hello
第二次传值
world
None
3
None
4
"""

3.多任务处理

def test1():
    while True:
        print("---1--")
        yield None

def test2():
    while True:
        print("---2--")
        yield None

# 只是定义了生成器(存储了数据生成的方式,等待调用)  协处理器
t1 = test1()
t2 = test2()
# 循环执行生成器中内容
while True:
    t1.__next__()
    t2.__next__()

2.迭代器

可迭代的: 凡是可以通过for循环取值的都是可迭代的
凡是可以被next函数调用取值,并且返回下一个值的对象就是一个迭代器
(生成器一定是一个迭代器,迭代器不一定就是生成器)
# 迭代器
text1 = "hello python"
# 使用iter()方法转换为迭代器
text = iter(text1)
# print(next(text))
# print(next(text))
# print(next(text))
# print(next(text))
# print(next(text))
"""
h
e
l
l
o
"""
# 自动输出
for i in text:
    print(i)

# 此外我们可以导入包来进行查看是否符合迭代器规则
from collections import Iterable

print(isinstance("abc",Iterable)) # True 
print(isinstance(123,Iterable)) # False 

3.闭包

什么是闭包?
    在一个函数中,又定义了一个函数,并且里面的函数使用了,外面的函数的参数,这个整体就是一个闭包

什么时候会用到闭包?
    外面的函数给定了基础条件,里面的函数基于原来的基础之上进行进一步处理
# 定义一个函数
def text(num):
    print("--1--")
    def text_in(): # 函数内定义一个函数
        print("--2--")
        print(num + 50) # 在原先函数的参数上增加
    print("--3--")
    return text_in

a = text(100)
# 👇 对变量a进行输出,执行到return text_in返回了该函数的内存地址就结束了并没有对该函数执行
print(a)
# 在text(100)赋值给a的基础上调用a方法 即a()执行text_in里的条件
a()
"""
--1--
--3--
<function text.<locals>.text_in at 0x017B2C88>
--2--
150
"""

闭包执行顺序图例:
在这里插入图片描述

1.闭包应用

# 闭包的应用
def text(func):
    def text_in():
        # 假设这里面是一堆你设置的条件
        # ……………
        print("已完成操作!")
        func()
    return text_in

def f1():
    print("hello")

def f2():
    print("python")

# 在定义函数text(参数)传入f1作为参数
print(text(f1)) # <function text.<locals>.text_in at 0x01DA2C88>
# 给定一个变量接收
f1 = text(f1)
f1() # 调用该方法
f2 = text(f2)
f2()
"""
已完成操作!
hello
已完成操作!
python
"""

4.装饰器

# 闭包的应用
def text(func):
    def text_in():
        # 假设这里面是一堆你设置的条件
        # ……………
        print("已完成操作!")
        func()
    return text_in

@text # 在函数上写入@对应的闭包函数就是装饰器
def f1():
    print("hello")

@text
def f2():
    print("python")

f1()
f2()
"""
已完成操作!
hello
已完成操作!
python
"""

1.多层装饰

#定义函数:完成包裹数据
def makeBold(fn):
    print("--makeBold--")
    def wrapped():
        print("----markBlod11111--")
        return "<b>" + fn() + "</b>"
    return wrapped

#定义函数:完成包裹数据
def makeItalic(fn):
    print("--makeItalic---")
    def wrapped():
        print("----makeItalic11111--")
        return "<i>" + fn() + "</i>"
    return wrapped

@makeItalic	 
@makeBold
def test1():
    return "初次见面!"

a = test1()

# 输出结果为
"""
--makeBold--
--makeItalic---
👆 因为调用了装饰器所以从上往下执行了闭包外函数的输出
👇 多层装饰器执行顺序为先执行离函数近的装饰器:makeBold,然后上层装饰器在下层执行完之后的结果进行再一次装饰输出
----makeItalic11111--
----markBlod11111--
"""

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值