• day12 装饰器的进阶


    1装饰器

    #装饰器的进阶
        #functools.wraps
        #带参数的装饰器
        #多个装饰器装饰同一个函数
    #装饰器:
        #本质:闭包函数
        #原则:开放封闭
        #作用:不改变原函数的调用方式的情况下 在函数的前后添加功能
    
    #装饰器
    def wrapper(func):
        def inner(*args,**kwargs):
            print('在被装饰的函数执行之前要做的事')
            ret=func(*args,**kwargs)
            print('在被装饰的函数执行之后要做的事')
            return ret
        return inner
    @wrapper
    def holiday(day):
        print("全体放假%s天" % day)
        return "很开心"
    
    print(holiday(3))
    <<<
    在被装饰的函数执行之前要做的事
    全体放假3天
    在被装饰的函数执行之后要做的事
    很开心

    *的聚合打散

    #接收的时候聚合 执行的时候打散
    def outer(*args):
        print(args)
        print(*args)
        def inner(*args):
            print("inner:",args)
        inner(*args)
    outer(1,2,3,4)#==outer(*[1,2,3,4])==outer(*(1,2,3,4))
    (1, 2, 3, 4)
    1 2 3 4
    inner: (1, 2, 3, 4)

    2.完美装饰器

    # 2 完美装饰器
    from functools import  wraps
    def wrapper(func):
        @wraps(func)
        def inner(*args,**kwargs):
            print('在被装饰的函数执行之前要做的事')
            ret=func(*args,**kwargs)
            print('在被装饰的函数执行之后要做的事')
            return ret
        return inner
    @wrapper
    def holiday(day):
        '''这是一个放假的通知'''
        print("全体放假%s天" % day)
        return "很开心"
    
    
    print(holiday(3))
    print(holiday.__name__) #打印函数的名字
    print(holiday.__doc__)  #打印函数的字符串注释
    <<<
    在被装饰的函数执行之前要做的事
    全体放假3天
    在被装饰的函数执行之后要做的事
    很开心
    holiday
    这是一个放假的通知
    def wahaha():
        '''
    一个打印娃哈哈的函数
        '''
        print('wahha')
    print(wahaha.__name__) #查看字符串格式的函数名
    print(wahaha.__doc__) #document 查看字符串格式的注释
    wahaha()
    
    <<<
    wahaha
    
    一个打印娃哈哈的函数
        
    wahha

    3.作业

    #1.编写一个装饰器 为多个函数加上认证功能(用户的账号密码来源于文件)
    #要求登陆成功一次 后续的函数都无需再输入用户名和密码
    FLAG=False
    def login(func):
        def inner(*args,**kwargs):
            global FLAG
            if FLAG:
                ret=func(*args,**kwargs)
                return ret
            else:
                username=input('username:')
                password=input('password:')
                if username=='hhh'and password=='123':
                    FLAG=True
                    ret = func(*args, **kwargs)
                    return ret
                else:
                    print('登录失败')
        return inner
    
    @login
    def shoplist():
        print('增加一件物品')
    @login
    def shoplist_remove():
        print('删除一件物品')
    shoplist()
    shoplist_remove()
    <<<
    username:hhh
    password:123
    增加一件物品
    删除一件物品
    #2 编写装饰器 为多个函数加上记录调用功能  要求每次调用函数都将被调用的函数名称写入文件
    def log(func):
        def inner(*args,**kwargs):
            with open('log','a',encoding='utf-8')as f:
                f.write(func.__name__+'
    ')
            ret=func(*args,**kwargs)
            return ret
        return inner
    
    @log
    def shoplist():
        print('增加一件物品')
    
    
    @log
    def shoplist_remove():
        print('删除一件物品')
        return  'shanchu'
    shoplist_remove()
    shoplist()
    # shoplist_remove()
    print(shoplist_remove())
    <<<
    删除一件物品
    增加一件物品
    删除一件物品
    shanchu
     
    #1.编写下载网页内容的函数 要求功能是:用户传入一个人url,函数返回下载页面的结果
    #2.为题目1编写装饰器 实现缓存网页内容的功能:
    #具体:实现下载的页面放入文件中,如果文件内有值(文件大小不为0),就优先从文件中读取网页内容
    #否则就去下载存到文件中
    #
    import os
    from urllib.request import urlopen
    def cache(func):
        def inner(*args,**kwargs):
            if os.path.getsize('web_cache'):
                with open('web_cache','rb') as f:
                    return  f.read()
            ret=func(*args,**kwargs)
            with open('web_cache','wb')as f:
                f.write(b'****'+ret)
            return ret
        return inner
    @cache
    def get(url):
        code=urlopen(url).read()
        return code
    
    ret=get('https://www.baidu.com/')
    print(ret)
    ret1=get('https://www.baidu.com/')
    print(ret1)
    ret=get('https://ilovefishc.com/html5/')
    print(ret)
    
    <<<
    b'<html>
    <head>
    	<script>
    		location.replace(location.href.replace("https://","http://"));
    	</script>
    </head>
    <body>
    	<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
    </body>
    </html>'
    b'****<html>
    <head>
    	<script>
    		location.replace(location.href.replace("https://","http://"));
    	</script>
    </head>
    <body>
    	<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
    </body>
    </html>'
    b'****<html>
    <head>
    	<script>
    		location.replace(location.href.replace("https://","http://"));
    	</script>
    </head>
    <body>
    	<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
    </body>
    </html>'

    4.装饰器的进阶

    1.带参数的装饰器

    #4 装饰器进阶
    #1 带参数的装饰器
    #500个函数
    import time
    FLAGE=False
    def timmer_out(flag):
        def timmer_out(func):
            def inner(*args,**kwargs):
                if flag:
                    start=time.time()
                    ret=func(*args,**kwargs)
                    end=time.time()
                    print(end-start)
                    return ret
                else:
                    ret = func(*args, **kwargs)
                    return ret
            return inner
        return timmer_out
    @timmer_out(FLAGE)
    def wahaha():
        time.sleep(1)
        print("wahahaha")
    @timmer_out(' ')
    def er():
        time.sleep(1)
        print("222222")
    wahaha()
    er()
    <<<
    wahahaha
    222222
    1.0006272792816162

    2.多个装饰器装饰同一个函数

    #2 多个装饰器装饰一个函数
    def wrapper1(func):
        def inner(*args,**kwargs):
            print("wrapper1 before func")
            ret=func(*args,**kwargs)
            print("wrapper1 after func")
            return ret
        return inner
    
    def wrapper2(func):
        def inner(*args,**kwargs):
            print("wrapper2 before func")
            ret=func(*args,**kwargs)
            print("wrapper2 after func")
            return ret
        return inner
    
    def wrapper3(func):
        def inner(*args,**kwargs):
            print("wrapper3 before func")
            ret=func(*args,**kwargs)
            print("wrapper3 after func")
            return ret
        return inner
    
    @wrapper1
    @wrapper2
    @wrapper3
    def f():
        print('in f')
        return "hhh"
    print(f())
    <<<
    wrapper1 before func
    wrapper2 before func
    wrapper3 before func
    in f
    wrapper3 after func
    wrapper2 after func
    wrapper1 after func
    hhh
  • 相关阅读:
    python_并发编程——数据共享
    python_并发编程——管道
    python_并发编程——消费者和生产者模型
    python_并发编程——队列
    python_并发编程——事件
    python_并发编程——锁
    python_并发编程——守护进程
    面试题-3
    CentOS7使用‘中科大源’
    date命令查看与修改
  • 原文地址:https://www.cnblogs.com/hi-python/p/10125216.html
Copyright © 2020-2023  润新知