Python高级语法闭包和装饰器


1.闭包

# 装饰器给已有的函数增加额外的功能,它的本质是一个闭包函数
# 闭包函数
# 函数,函数调用完之后,内部定义的变量直接销毁了,但是有时候我们需要保存函数内的这个变量
# 在这个变量进行一些其他操作,比如求和
# 闭包:
# 形成条件
# 1.实现函数嵌套
# 2.内部函数使用外部函数的变量
# 3.外部函数返回内部函数的名字,不要加括号

# 简单写个闭包
def tes01(a):
    b = 1
    def tes02():
        print(a,b)
    return tes02


# a = test02
a = tes01(6)
# test02()
a()
# print里面会返回什么 6,1
# 步骤:是怎么运行的?
# 函数是从上到下执行,只要在函数调用 也就是函数名()才会执行到函数内部
# 不会走到test02 test02()才会执行到test02函数内部

# return 返回test02 test02给谁?

# 定义两个数字相加求和
# result = num1 + num2 num1+=num2 可以吗?1 不可以2

def outer(num1):
    print(num1)
    def inner(num2):
        result = num1 + num2
        print(result)
    return inner

# inner只是一个名, 没加()
# 不是固定写法 c是变量名随便取 c就是为了取 inner
c = outer(5)
c(9)

# 函数从上到下执行,只有函数名(参数)的时候才会执行
# 打印print(5)

# print之后
# 1.outer(5)先走入到outer(num1)函数内部,num1就是5,打印出来的也是5
# 接下来不会走入到inner(num2)函数内部。返回inner给到outer(5),所以outer(5)就是inner.
# c = inner c(9)就相当于inner(9)触发了函数条件.打印出来的就是14
# def inner(num2):
#     result = num1 + num2
#     print(result)
# 没有触发条件 inner(num2)
# 返回inner a就是inner c(9) == inner(9)
def outer(num1):
    print(num1)
    def inner(num2):
        nonlocal num1
        num1+=num2
        print(num1)
    return inner

d = outer(5)
d(8)

# 定义一下num1编程global
# 不用global定义修改值用于不同函数 这里用nonlocal:作用对象是外层的变量,就是用在闭包里面

# 普及知识点: 局部变量
# 局部变量: 定义在函数内部
# 全局变量: 定义在函数外部
# num1 = 100
def tes01(num2):
    #局部变量
    num2 = 3
    def tes02(num1):
    # 局部里面不能直接修改外部变量
    # 在函数内部要修改全局变量的值 用到global
        nonlocal num2
        num2 += num1
        print(num1)
    return tes02
e = tes01(5)
e(3)

# 闭包的作用: 变量不会污染全局变量, 不会因为外部函数调用而销毁掉

2.装饰器

# 装饰器:就是给已有的函数增加额外的功能
# 特点:
# 不需要修改原有的代码,就能增加函数额外的功能
# 不用修改调用方式

# 发表评论 检查一下我有没有登录 没有登录 登录一下
# 闭包
# check(comment)
def check(fc):
    print('装饰器函数执行')
    def inner():
        print('请先登录')
        fc()
    return inner
# check(comment)
@check
def comment():
    print('发表评论')

# 调用方式更改了
# f = check(comment)
# f()

# 装饰器的语法糖改一下 @额外函数的功能
comment()

# @check装饰器 怎么去运行的?@check相当于代理
# 现在要运行comment()代理人预约走入到
# 1.先打印 print('装饰器函数执行')
# 不会走入到inner函数内部,没有被调用,返回inner 这个inner返回给谁
# inner返回给秘书inner = comment()
# 2.print('请先登录')
# 3.fc() fc是comment comment()

3.练习题目

# 现在有个函数,想要知道这个函数执行了多长时间
import time
def decorate(fc):
    def inner():
        # 获得当前的时间
        print(time.strftime('%Y-%m-%d %H:%M:%S'))
        t_starttime = time.time()
        b=fc()
        print(b)
        #  结束时间的时间戳
        t_endtime = time.time()
        print(time.strftime('%Y-%m-%d %H:%M:%S'))
        # 结束时间 - 开始时间秒数 = 剩余秒数
        print('总共花了%.5f'%(t_endtime - t_starttime))
        return 1314
    return inner

# decorate(tes01)
@decorate
def tes_01():
    time.sleep(2)
    print('函数在执行中')
    return 520

g = tes_01()
print(g)

4.迭代器

# 自定义迭代器里面 iter 还有一个next
# 数据类型:字符串 列表 元组 集合字典 是不是可以用for循环拿到里面的数据类型
# for里面是怎么运行 台前看不到
# 特殊方法__iter__() 返回一个迭代器对象,迭代器对象里面在用__next__()把里面的数据拿出来
# 多拿了一个
a = [1,2,3,4]
b = (1,2,3)
# print(a.__iter__())
# print(b.__iter__())
iterA =a.__iter__()
print(iterA.__next__())
print(iterA.__next__())
print(iterA.__next__())
print(iterA.__next__())

5.生成器

# 也就是一个特殊的迭代器,使用yield的函数就被称为生成器,不是一个普通的函数了

5.1第一种yield

def gen(n):
    # 0,1,2,3,4
    for i in range(n):
        # 每次遇到yield时候函数暂停并报错当前的运行信息
        yield i * i

# 不会直接进入gen(5)生成器内部,需要循环或者next才会进入到生成器函数内部
x = gen(5)
for i in x:
    print(i)

5.2第二种推导式外层()用也表示生成器

gen = (i * i for i in range(5))
for i in gen:
    print(i)
def gen():
    yield
print(gen())

# send方法实现生成器内部进行数据交互
# close关闭生成器
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

司小幽

真诚赞赏,手留余香。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值