python生成器、推导式、装饰器

1、生成器(generator)

  • 迭代器的概念:可以被next()函数调用,并不断返回下一个值的对象称为迭代器,也可以理解为迭代器是方法可迭代对象的工具。

  • 生成器的概念和使用:生成器是一种特定的迭代器,生成器是散装的使用next()函数来获取迭代器内部的数据(就是写一个next()获取一个元素,以此类推),它适合遍历很大的数据集合,节省内存,提升运行速度

1.1、生成器的两种表达形式:推导式、函数
  • 生成器的函数概念:生成器函数就是在自定义函数里面加yield关键字,这个函数就变成了生成器函数

  • yield关键字的概念和功能:跟return一样可以把数据返回给函数调用语句处,但是yield关键使函数中断并保存中断状态,也就是下一次运行时会接着运行上一次剩下的代码

def ot():
def ot():
    for i in range(5):
        yield I

n =ot()
print(next(n))
print(next(n))

//结果
0
1
1.2、推导式
  • 概念:python推导式是一种独特的数据处理方式。是可以从一个数据序列构建成另一个新的数据序列的结构体。

  • 列表推导式写法
    [列表元素 for 迭代变量 in 迭代对象]
    [列表元素 for 迭代变量 in 迭代对象 if 条件]

//10以内的偶数
ls = [n for i in range(10) if i%2==0]
print(ls)
  • 元组推导式写法(这是一个生成器)
    (列表元素 for 迭代变量 in 迭代对象)
    (列表元素 for 迭代变量 in 迭代对象 if 条件)

generator1 = (i for i in range(11) if i % 2 == 0)
print(generator1)   # <generator object <genexpr> at 0x000001B643093F40>
### 上面的generator1已经是一个生成器对象了,所以不能直接查看里面的元素,需要使用next()函数来进行调用
print(next(generator1))    # 0
print(next(generator1))    # 0

注意:这两种推导式是使用for循环生成序列的一种结合体,其中元组推导式是生成器

2、装饰器

  • 装饰器本质:装饰器本质上是一个闭包函数

    • 闭包的构成:
      • 1、必须是嵌套函数
      • 2、内层函数中必须要用到外函数的一个非全局变量
      • 3、外函数的return返回值必须是内函数的名字
  • 作用:在不修改原函数的情况下,添加额外的功能。被装饰的函数通常称为业务函数

  • 业务函数被装饰器进行装饰(添加额外功能)的本质:在装饰函数里面写好额外的功能代码。把业务函数的调用语句放到装饰器里面去执行,所以业务函数正真的调用夹在装饰器内部额外功能代码的上下左右去执行的,以此达到被额外功能装饰的效果。

2.1装饰器函数基础写法格式

def ot(func):#形参用来接收【被装饰函数】的名字
    def inner(*args, **kwargs):
        #在此添加函数执行之前要执行的代码块
        result=func(*args,**kwargs)
        #在此添加函数执行之后要执行的代码块
        return result
    return inner

2.2装饰器函数的两种装饰写法

  • 直接在装饰器函数调用语句里面将业务函数的名字写成实参传给装饰器函数的形参来插入到额外功能代码中进行调用装饰。
'''
题目:制作一个游戏系统
    这个游戏系统的游戏界面需要进行注册才能进入游戏内部,
    这个注册程序的功能是:账号和密码的输入以及显示给用户看;
    在这个注册程序的前后【需要有一些修饰的文字】来让这个注册功能达到【更好的可读性】:
        1、在用户【进入游戏界面后】,需要加一句欢迎词和提示语:'欢迎来到吃鸡游戏,请先注册,再登录游戏!!'
        2、在用户【注册完成之后】弹出一句提示语:'您已注册成功,即将跳转到登录页面!!!'
'''
# 由题可知:注册程序是【业务函数】,两句修饰文字是【装饰器】内部的额外功能代码。
# 制作注册函数:(业务函数)
def register():
    name = input('请输入你要注册的账号:')
    passwd = input('请输入你要注册的密码:')
    print(f'您注册的账号和密码分别是:{name},{passwd}')

# 制作装饰器函数:(闭包)
def ot(n):    # n = register
    def inner(game):
        print(f'欢迎来到{game}游戏,请先注册,再登录游戏!!')
        n()    # 这里是调用register函数:register()
        print('您已注册成功,即将跳转到登录页面!!!')
    return inner

# 第一种启动整个程序(装饰的执行过程)的方式:调用装饰器函数来启动整个系统
ot(register)(input('请输入要进入的游戏名字:'))

'''
情况1为:
欢迎来到吃鸡游戏,请先注册,再登录游戏!!
请输入你要注册的账号:lucy
请输入你要注册的密码:123456
您注册的账号和密码分别是:lucy,123456
您已注册成功,即将跳转到登录页面!!!
'''

  • 通过语法糖@来进行传参调用装饰。
# 第二种启动整个程序(装饰的执行过程)的方式:用语法糖@把装饰器的外函数调用语句给到【业务函数】,直接调用【业务函数】来启动整个程序
# 制作装饰器函数:(闭包)
def ot(n):    # n = register
    def inner(game):
        print(f'欢迎来到{game}游戏,请先注册,再登录游戏!!')
        n()    # 这里是调用register函数:register()
        print('您已注册成功,即将跳转到登录页面!!!')
    return inner


# 制作注册函数:(业务函数)
@ot     # 这句相当于是:ot(register)
def register():
    name = input('请输入你要注册的账号:')
    passwd = input('请输入你要注册的密码:')
    print(f'您注册的账号和密码分别是:{name},{passwd}')

register(input('请输入要进入的游戏名字:'))    # 这句代码就是装饰器内函数的调用语句:inner()
'''
结果为:
请输入要进入的游戏名字:无畏契约
欢迎来到无畏契约游戏,请先注册,再登录游戏!!
请输入你要注册的账号:tina
请输入你要注册的密码:987654
您注册的账号和密码分别是:tina,987654
您已注册成功,即将跳转到登录页面!!!
'''

@+装饰器名称(函数名) 表示装饰器的使用。调用了装饰器函数:装饰器函数名(参数)。

def varibales(f):#f使用装饰器的函数体f=cat
    def var():
        f()#f()=cat()
        print("猫抓鱼")
    return var

@varibales  #varibales(参数)解释器自动执行了
def cat():  #使用装饰器后cat()=var()
    print("猫上树")
cat()

  • 多装饰器时从近到远执行
def varibales(f):#f使用装饰器的函数体f=cat
    def var():
        f()#f()=cat()
        print("猫抓鱼")
    return var


def varibales1(f):#f使用装饰器的函数体f=var
    def var1():
        f()#f()=var()
        print("猫抓鸟")
    return var1

@varibales1
@varibales  #varibales(参数)解释器自动执行了
def cat():  #使用装饰器后cat()=var1()
    print("猫上树")
cat()

装饰器:@+函数名=解释器自动执行调用函数(函数名(参数))。函数体作为另一函数的参数传入在返回函数体。
不修改愿函数为函数扩展新的功能。

装饰器.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容