zoukankan      html  css  js  c++  java
  • python_11 装饰器,闭包

    装饰器:本质就是函数,功能是为其他函数添加附加功能

    原则:

    1.不修改被修饰函数的源代码

    2.不修改被修饰函数的调用方式

    装饰器的知识储备

    装饰器=高阶函数+函数嵌套+闭包

    #装饰器:
    def timmer(func):
        def wrapper(*args,**kwargs):
            time1=time.time()
            res=func(*args,**kwargs)
            time2=time.time()
            print('函数的运行时间是%d'%(time2-time1))
            return res
        return wrapper
    
    
    @timmer
    def cal(l):
        res=0
        for i in l:
            res+=i
            time.sleep(0.1)
        return res
    
    a=cal(range(10))
    
    print(a)
    
    >>>函数的运行时间是1
    45

    高阶函数定义:

    1.函数接收的是一个函数名

    2.函数的返回值是一个函数名

    3.满足上述任意一个条件都可以称之为高阶函数

    import time
    
    def foo():
        time.sleep(0.5)
        print("sadfa")
    
    def test(func):
        print(func)
        t1=time.time()
        func()
        t2=time.time()
        print("函数的运行时间是%ds"%(t2-t1))
    
    test(foo)#修改了函数的调用方式
    #不修改源代码
    #不修改foo调用方式
    #多运行了一次,不合格
    def foo():
        time.sleep(1)
        print("from the foo")
    
    def dec(func):
        t1=time.time()
        func()
        t2=time.time()
        print("%s的运行时间是%d"%(func,(t2-t1)))
        return func
    
    foo=dec(foo)
    foo()


    函数的闭包:闭包是由函数及其相关的引用环境组合而成的实体,如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。

    def father(name):
        print('from father %s'%name)
        def son():
            print('my father is %s'%name)
            def grandson():
                print('my grandpa is %s'%name)
            grandson()
        son()
        print(locals())
    
    father('alex')
    
    
    >>>from father alex
    my father is alex
    my grandpa is alex
    {'son': <function father.<locals>.son at 0x00000169A59B7268>, 'name': 'alex'}


    装饰器框架:

    #装饰器框架
    def timmer(func):
        def wapper():
            print(func)
            func()
        return wapper
    def timmer_test(func):
        def add_time():
            t1=time.time()
            func()
            t2=time.time()
            print('该函数的运行时间是%d'%(t2-t1))
        return add_time
    
    def test():
        time.sleep(2)
        print('test函数运行完毕')
    
    
    test=timmer_test(test)
    test()
    
    >>>test函数运行完毕 该函数的运行时间是2

    @语法糖:

    def timmer(func):
        def add_time():
            t1=time.time()
            func()
            t2=time.time()
            print('该函数的运行时间是%d'%(t2-t1))
        return add_time
    
    @timmer#@timmer 就相当于test=timmer(test)
    def test():
        time.sleep(2)
        print('test函数运行完毕')
    
    test()
    
    >>>test函数运行完毕
    该函数的运行时间是2


    函数闭包加上返回值:

    def timmer(func):
        def add_time():
            t1=time.time()
            res=func()
            t2=time.time()
            print('该函数的运行时间是%d'%(t2-t1))
            return res
        return add_time
    
    @timmer#@timmer 就相当于test=timmer(test)
    def test():
        time.sleep(2)
        print('test函数运行完毕')
        return '这是test的返回值'
    
    res=test()#这里就是在运行add_time
    print(res)
    
    
    >>>test函数运行完毕
    该函数的运行时间是2
    这是test的返回值


    再加上参数:

    def timmer(func):
        def add_time(*args,**kwargs):
            t1=time.time()
            res=func(*args,**kwargs)
            t2=time.time()
            print('该函数的运行时间是%d'%(t2-t1))
            return res
        return add_time
    
    @timmer#@timmer 就相当于test=timmer(test)
    def test(name,age):
        time.sleep(2)
        print('test函数运行完毕,名字是%s,年龄是%d'%(name,age))
        return '这是test的返回值'
    
    @timmer
    def test1(name,age,gender):
        time.sleep(3)
        print('test1函数运行完毕,名字是%s,年龄是%d,性别是%s'%(name,age,gender))
        return '这是test1的返回值'
    
    res=test('alex',19)#这里的test是运行的add_time
    print(res)
    res1=test1('sb',20,'male')
    print(res1)
    
    
    >>>test函数运行完毕,名字是alex,年龄是19
    该函数的运行时间是2
    这是test的返回值
    test1函数运行完毕,名字是sb,年龄是20,性别是male
    该函数的运行时间是3
    这是test1的返回值

    解压序列:

    a,b,c='hel'
    print(a,b,c)
    
    
    e,f,g=(4,5,6)
    print(e,f,g)
    
    
    
    #取出第一个值和最后两个值
    l=['alex',7,8,9,7,8,5,2,1,5,6,4,8,6,4,6,'is','sb']
    
    #*_代表中间所有的值,_可以换成任意值
    x,*_,y,z=l
    print(x,y,z)
    
    >>>h e l
    4 5 6
    alex is sb


    调换两变量的值:

    a=20
    b=100
    a,b=b,a
    print(a,b)
    
    >>>100 20

    装饰器加上验证功能:

    user_dic={'name':None,'login':False}
    
    def yanzheng(func):
        global zt
        def wapper(*args,**kwargs):
            if user_dic['name'] and user_dic['login']:
                res=func(*args,**kwargs)
                return
            name=input('请输入用户名:').strip()
            psw=input('请输入密码:').strip()
            if  name=='alex' and psw=='123':
                res=func(*args,**kwargs)
                user_dic['name']=name
                user_dic['login']=True
                return res
            else:
                print('用户名或密码错误')
        return wapper
    
    @yanzheng
    def index():
        print('欢迎来到京东主页')
    
    @yanzheng
    def home(name):
        print('欢迎回家%s'%name)
    
    @yanzheng
    def car(name):
        print('%s的购物车里有%s'%(name,'奶茶'))
    
    index()
    home('alex')
    car('alex')
    
    >>>请输入用户名:alex
    请输入密码:123
    欢迎来到京东主页
    欢迎回家alex
    alex的购物车里有奶茶
    user_list=[
        {'user_name':'alex','psw':'123'},
        {'user_name':'blex','psw':'456'},
        {'user_name':'clex','psw':'789'},
        {'user_name':'dlex','psw':'0'}
    
    ]
    
    
    
    current_zt={'name':None,'login':False}
    
    def yanzheng(func):
        def wapper(*args,**kwargs):
            global user_name
            if current_zt['name'] and current_zt['login']:
                res=func(*args,**kwargs)
                return res
            user_name=input('请输入用户名:').strip()
            psw=input('请输入密码:').strip()
            for user_dic in user_list:
                if  user_name==user_dic['user_name'] and psw==user_dic['psw']:
                    res=func(*args,**kwargs)
                    current_zt['name']=user_name
                    current_zt['login']=True
                    return res
            else:
                print('用户名或密码错误')
        return wapper
    
    @yanzheng
    def index():
        print('欢迎来到京东主页')
    
    @yanzheng
    def home():
        print('欢迎回家%s'%user_name)
    
    @yanzheng
    def car():
        print('%s的购物车里有%s'%(user_name,'奶茶'))
    
    index()
    home()
    car()
    
    >>>请输入用户名:blex
    请输入密码:456
    欢迎来到京东主页
    欢迎回家blex
    blex的购物车里有奶茶

    将原装饰器加上参数:直接在最外层加一个函数带上参数,使用装饰器时也需带上参数

    user_list=[
        {'user_name':'alex','psw':'123'},
        {'user_name':'blex','psw':'456'},
        {'user_name':'clex','psw':'789'},
        {'user_name':'dlex','psw':'0'}
    
    ]
    
    
    
    current_zt={'name':None,'login':False}
    
    
    def renzhen(type='ldb'):
        def yanzheng(func):
            def wapper(*args,**kwargs):
                global user_name
                print('认证类型是%s'%type)
                if type=='ldb':
                    if current_zt['name'] and current_zt['login']:
                        res=func(*args,**kwargs)
                        return res
                    user_name=input('请输入用户名:').strip()
                    psw=input('请输入密码:').strip()
                    for user_dic in user_list:
                        if  user_name==user_dic['user_name'] and psw==user_dic['psw']:
                            res=func(*args,**kwargs)
                            current_zt['name']=user_name
                            current_zt['login']=True
                            return res
                    else:
                        print('用户名或密码错误')
                elif type=='abb':
                    print('不知道这个类型')
                    res = func(*args, **kwargs)
                    return res
                else:
                    print('类型错误')
                    res = func(*args, **kwargs)
                    return res
            return wapper
        return yanzheng
    
    @renzhen(type='ldb')
    def index():
        print('欢迎来到京东主页')
    
    @renzhen(type='abb')
    def home():
        print('欢迎回家%s'%user_name)
    
    @renzhen(type='sss')
    def car():
        print('%s的购物车里有%s'%(user_name,'奶茶'))
    
    index()
    home()
    car()
  • 相关阅读:
    Scrapy框架基础使用
    python爬虫练习--爬取今日头条街拍图片
    python爬虫练习--爬取所有微博
    python爬虫练习--爬取猫眼热映口碑榜
    python练习---校园管理系统
    python爬虫练习--爬取猫眼top100电影信息
    基础篇-Python的urllib库
    1--爬虫环境安装篇
    Confluence 如何查看页面 ID
    导入 Gradle 项目到 IntelliJ IDEA
  • 原文地址:https://www.cnblogs.com/Manuel/p/10637930.html
Copyright © 2011-2022 走看看