python基础学习-13

闭包函数和装饰器

13.1.1 闭包函数

  • 闭:封闭,关闭

  • 包:包装起来的函数,对函数进行处理的数据,内层函数。

(1)闭包函数的构成条件

  • 一定要是嵌套函数

  • 内层函数要返回给外层函数

  • 内层函数要使用外层函数的变量

(2)闭包的作用

  • 可以写装饰器

  • 可以保存外部函数的变量

语法格式:
def out():
    name = 0
    def inner():
        pass
    return inner
-----------------------------
当函数调用的时候里面的代码执行,执行完毕之后随后变量销毁
def out():
    a = 10
    def inner(b):
        nonlocal a
        a+=b
        print(a)
    return inner
​
res = out()
res(10)
res(10)
res(10)
-----------------------------------
def out(name):
    def inner(msg):
        print(f'{name}:{msg}')
    return inner
​
heihei = out('嘿嘿')
student = out('李广')
heihei('出来玩最重要的是什么?')
student('不知道!')
heihei('出来玩最重要的是出来')
student('好的我这就出来')
  • 函数内部定义的变量可以访问外层函数的变量(参数)

  • 闭包的作用

    • 封闭数据:将数据封装起来形成独立的作用域,避免全局变量的污染,提高代码安全性

    • 保持状态,闭包可以保持外层函数的状态,即使外部函数执行完毕,闭包仍然可以访问外层函数的变量或者数据

    • 实现装饰器:闭包装饰器。本质上就是一个闭包。

    13.2.1 装饰器

    装饰器:本质上就是一个闭包

    作用:在不修改代码的前提下,给另外的函数添加新的功能,并且可以反复使用。

def fly(someone):
    wings = 0
    def install():
        nonlocal wings
        wings+=1
        someone()
        print(f'我用有{wings}双翅膀')
    return install
​
@fly
def hello():
    print('大家好我是周杰伦')
​
hello()
​
@fly
def hello1():
    print('大家好我是heihei')
hello1()
​
# res = fly(hello)
# res()
​
语法糖:@+外层函数的函数名
​
------------------------------------------------------
写一个装饰器,判断函数运行的时间
import time
# print(time.time())
​
def runtime(fun):
    def timer():
        time_s = time.time()
        fun()
        time_res=time.time()-time_s
        print(f'函数运行的时间是{time_res}秒')
    return timer
​
@runtime
def func1():
    for i in range(1000001):
        print(i)
func1()
# res = runtime(func1)
# res()
-----------------------------------------------------
def verify(login):
    def inner():
        b = login()
        if len(b) == 11:
            if b.isdigit():
                print('登录成功')
            else:
                print('登录失败,电话必须是纯数字,请重新登录')
                login()
        else:
            print('登录失败,电话必须是11位,重新登录')
            login()
    return inner
​
@verify
def phone():
    a = input('请输入电话号码')
    return a
​
phone()

13.3.1 带参装饰器

1 装饰器内层函数有参数的时候,被装饰函数没有参数的时候,可以通过被装饰函数给内层函数传参数。
​
def func(num):
    n = 10
    def hello(a):
        nonlocal n
        num()
        n+=a
        print(n)
    return hello
@func
def qiuhe():
    print('年龄是')
qiuhe(10)
​
2被装饰函数有参数和返回值的时候,装饰器内层函数和内层函数里面的函数都要有参数和返回值。
​
def func(qiuhe):
    n = 10
    def hello(name):
        nonlocal n
        qiuhe(name)
        n+=1
        print(n)
    return hello
@func
def qiuhe(name):
    print(f'{name}的年龄是')
qiuhe('tunk')
​
3 为了代码复用 万能用法
def func(qiuhe):
    n = 10
    def hello(*args,**kwargs):
        nonlocal n
        qiuhe(*args,**kwargs)
        n+=1
        print(n)
    return hello
@func
def qiuhe(name):
    print(f'{name}的年龄是')
qiuhe('tunk')

小练习: 

写一个装饰器,让函数重复执行5次
​
装饰器---把被装饰函数传到 闭包内 结合闭包内的代码增加新的功能。
​
for 循环 运行函数5次就行
​
---------
写装饰器
1写好闭包模版
2给外层函数写参数把被装饰函数传入闭包在闭包里面调用。
3设计代码给被装饰函数添加功能
4注意内层函数的参数怎么写
5写语法糖
6直接调用被装饰的函数

 答案:

def fun(num):
    def fun1():
        for i in range(1,6):
            num()
    return fun1


@fun
def handsome():
    print('我是大帅哥!!!')

handsome()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值