zoukankan      html  css  js  c++  java
  • 装饰器

    装饰器基础

    装饰器的目的是为了给被装饰 对象,增加新功能,或者说增加某种能力

    在程序中工具就是函数

    如此一来,装饰器指的就是一个函数,被装饰着也是一个函数

    总结;装饰器就是用一个函数去拓展另外一个已存在的函数的功能

           拓展性是对于一个应用程序来说非常重要的能力,任何应用程序都需要拓展,于是出现了开闭原则

    开闭原则:

        对修改关闭,对拓展开放

        不允许修改源代码以及调用方式

        装饰器就是一种可以保证不修改源代码,也不修改调用方式,还能给函数添加新功能的方式

    需求:  目前已有一个函数,其功能是从服务器下载一个文件,需求要为这个函数统计下载耗时

    import   time(下载功能)

    def download(filepath):

        print('开始下载%s’% filepath)

        time.sleep(3)

        print('下载完成%s’% filepath)

        return  '123'

    def upload():

        print('开始上传’)

        time.sleep(3)

        print('上传完成’)

        return  '123'

    def outer(func)

        def run_time(*args ,**kwargs )

            boot_time=time.time()

             res=func(*args,**kwargs)

             print('耗时',time.time()-boot_time)

             return res

        return run_time

    download = outer(download)

    movie = download('大电影’)

    print(movie)

    upload=outer(upload)

    upload()

    无参函数:

    import time
    def download():
    print("download run!")

    # ===============================
    def outer(func):
    def run_time(*args,**kwargs): #是为了让装饰函数能接受任何形式任何长度的参数
    boot_time = time.time()
    res = func(*args,**kwargs) # 将参数在原模原样交给被装饰者
    print("耗时:", time.time() - boot_time)
    return res # 把原始函数的执行结果 在交给调用者
    return run_time
    download = outer(download)
    # ==============================

    # 使用者
    download()

    有参函数
    from functools import wraps
    import time
    def outer(location):
    def logger(func):
    @wraps(func) # wrapper.__doc__ = func.__doc__
    def wrapper(*args, **kwargs):
    """这是装饰器函数"""
    if location == "cmd":
    print("时间:%s func:%s" % (time.time(), func.__name__))
    elif location == "file":
    with open("a.log", "a", encoding="utf-8") as f:
    f.write("时间:%s func:%s" % (time.time(), func.__name__))
    else:
    print("位置错误........必须是 file 或 cmd")
    return func(*args, **kwargs)
    return wrapper
    return logger

    @outer("file") # ????? logger = outer("file) test = logger(test)
    def test():
    """这是一个test函数"""
    print("test run!")

    # test()
    print(test.__doc__)(功能是调出注释)

    装饰器语法糖
    """
    语法糖
    就是一种简便写法,使你的语法更简洁

    """
    # 提供输出日记(日志 什么时候干了什么事)功能
    import time
    def logger(func):
    def wrapper(*args,**kwargs):
    print("时间:%s func:%s" % (time.time(),func.__name__))
    res = func(*args,**kwargs)
    return res
    return wrapper

    # 该语法就可以帮我们完成对原始函数的伪装,
    # 注意 1.必须写在被装饰函数的正上方
    # 注意 2.在开发时装饰器必须写在被装饰函数之上
    @logger # login = logger(login)
    def login():
    print("登录成功...")
    login()
    装饰器在购物车中的使用
    is_login = False

    # 判断是否登录过的装饰器
    def auth(func):
    def wrapper(*args,**kwargs):
    if is_login:
    func(*args,**kwargs)
    else:
    print("还没有登录过请先登录...")
    login()
    return wrapper


    def login():
    global is_login
    name = input("name:").strip()
    pwd = input("pwd:").strip()
    if name == "blex" and pwd == "123":
    print("登录成功!")
    is_login = True

    @auth
    def shopping():
    print("查看购物车....")

    @auth
    def collection():
    print("查看收藏....")


    def main():
    while True:
    funcs = {"1":login,"2":shopping,"3":collection}
    print("""
    1.登录
    2.购物车
    3.收藏夹
    """)
    res = input(">>>:").strip()
    if res in funcs:
    funcs[res]()
    else:
    print("输入有误!")
    main()


    同时叠加多个装饰器
    import time
    # 装饰器1
    def logger(func):
    def wrapper(*args,**kwargs):
    print("时间:%s func:%s" % (time.time(),func.__name__))
    res = func(*args,**kwargs)
    return res
    return wrapper

    #装饰器2
    def timer(func):
    def run_time(*args,**kwargs):
    boot_time = time.time()
    res = func(*args,**kwargs) # 这是在执行原始的download函数也就是被装饰的函数
    print("耗时:", time.time() - boot_time)
    return res # 把原始函数的执行结果 在交给调用者
    return run_time


    # 该语法就可以帮我们完成对原始函数的伪装,
    # 注意 1.必须写在被装饰函数的正上方
    # 注意 2.在开发时装饰器必须写在被装饰函数之上
    @timer # logger = timer(logger)
    @logger # login = logger(login)
    def login():
    print("登录成功...")
    login()
    # 在嵌套多个装饰器时,执行的顺序是 从上往下依次调用,结束的顺序反过来,是从下往上
    # 实际开发中 没什么用.....
    小节
    1.装饰器
    什么是装饰器,一种为其他函数增加新功能的函数就是装饰器
    装饰器是基于闭包函数实现的
    可以在遵循开闭原则的前提下,扩展新功能

    无参:
    def outer(func):
    def wrapper(*args,**kwargs):
    # 新功能
    res = func(*args,**kwargs)
    return res
    return wrapper

    有参
    def big_outer(arg):
    def outer(func):
    def wrapper(*args,**kwargs):
    # 新功能
    res = func(*args,**kwargs)
    return res
    return wrapper
    return outer
     
     
     


  • 相关阅读:
    Ubuntu 16.04 LTS nodejs+pm2+nginx+git 基础安装及配置环境(未完,未整理)
    JavaScript 二、eval 和 with 函数
    JavaScript 一、 ES6 声明变量,作用域理解
    UNMET PEER DEPENDENCY @angular/common@2.3.1
    Laravel Homestead 离线安装
    mac os x 记录 转载
    Ubuntu 16.04 LTS 完善解决亮度调整
    oh my zsh 切换 bash
    关于bitmap储存图片报内存不足的问题
    .net操作sqlserver数据库
  • 原文地址:https://www.cnblogs.com/tangda/p/10272183.html
Copyright © 2011-2022 走看看