装饰器基础

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

在程序中工具就是函数

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

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

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

开闭原则:

    对修改关闭,对拓展开放

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

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

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

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()

无参函数:

  1. import time
    def download():
    print("download run!")
  2.  
  3. # ===============================
    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)
    # ==============================
  4.  
  5. # 使用者
    download()
  1. 有参函数
  1. 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
  2.  
  3. @outer("file") # ????? logger = outer("file) test = logger(test)
    def test():
    """这是一个test函数"""
    print("test run!")
  4.  
  5. # test()
    print(test.__doc__)(功能是调出注释)
  1. 装饰器语法糖
  1. """
    语法糖
    就是一种简便写法,使你的语法更简洁
  2.  
  3. """
    # 提供输出日记(日志 什么时候干了什么事)功能
    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
  4.  
  5. # 该语法就可以帮我们完成对原始函数的伪装,
    # 注意 1.必须写在被装饰函数的正上方
    # 注意 2.在开发时装饰器必须写在被装饰函数之上
    @logger # login = logger(login)
    def login():
    print("登录成功...")
    login()
    装饰器在购物车中的使用
  1. is_login = False
  2.  
  3. # 判断是否登录过的装饰器
    def auth(func):
    def wrapper(*args,**kwargs):
    if is_login:
    func(*args,**kwargs)
    else:
    print("还没有登录过请先登录...")
    login()
    return wrapper
  4.  
  5. def login():
    global is_login
    name = input("name:").strip()
    pwd = input("pwd:").strip()
    if name == "blex" and pwd == "123":
    print("登录成功!")
    is_login = True
  6.  
  7. @auth
    def shopping():
    print("查看购物车....")
  8.  
  9. @auth
    def collection():
    print("查看收藏....")
  10.  
  11. 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()
  12.  
  13. 同时叠加多个装饰器
  1. 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.  
  3. #装饰器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
  4.  
  5. # 该语法就可以帮我们完成对原始函数的伪装,
    # 注意 1.必须写在被装饰函数的正上方
    # 注意 2.在开发时装饰器必须写在被装饰函数之上
    @timer # logger = timer(logger)
    @logger # login = logger(login)
    def login():
    print("登录成功...")
    login()
    # 在嵌套多个装饰器时,执行的顺序是 从上往下依次调用,结束的顺序反过来,是从下往上
    # 实际开发中 没什么用.....
    小节
  1. 1.装饰器
    什么是装饰器,一种为其他函数增加新功能的函数就是装饰器
    装饰器是基于闭包函数实现的
    可以在遵循开闭原则的前提下,扩展新功能
  2.  
  3. 无参:
    def outer(func):
    def wrapper(*args,**kwargs):
    # 新功能
    res = func(*args,**kwargs)
    return res
    return wrapper
  4.  
  5. 有参
    def big_outer(arg):
    def outer(func):
    def wrapper(*args,**kwargs):
    # 新功能
    res = func(*args,**kwargs)
    return res
    return wrapper
    return outer
  1.  
  1.  
  1.  
  1.  

day 13 装饰器的更多相关文章

  1. Python基础:13装饰器

    装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的应用有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同 ...

  2. Python Day 13 装饰器

    阅读目录   内容回顾 函数嵌套的定义 global.nonlocal关键字 闭包及闭包的运用场景 开放封闭原则 装饰器 一个函数被多次装饰 ##内容回顾 1.函数对象:函数名 => 存放的是函 ...

  3. python 基础之第十天(闭包,装饰器,生成器,tarfile与hashlib模块使用)

    局部变量与全局变量 局部变量:在函数里面定义的,只有当函数活动时才生效 全局变量:不在函数里面的 In [1]: x=10 In [2]: def bar(): ...: x=20 ...: prin ...

  4. 13、python中的函数(闭包与装饰器)

    一.嵌套函数 函数的内部又再定义另一个函数,这个函数就叫嵌套函数,里面含函数就叫内部函数. 示例: 二.返回函数 函数可以接收函数对象作为参数,同理函数也能返回一个函数对象作为返回值. 示例: 返回函 ...

  5. 13.Python略有小成(装饰器,递归函数)

    Python(装饰器,递归函数) 一.开放封闭原则 ​ 软件面世时,不可能把所有的功能都设计好,再未来的一两年功能会陆续上线,定期更新迭代,软件之前所用的源代码,函数里面的代码以及函数的调用方式一般不 ...

  6. 【0812 | Day 13】闭包函数/装饰器/迭代器

    目录 闭包函数 无参装饰器 有参装饰器 迭代器 闭包函数 一.什么是闭包? 闭包指的是:函数内部函数对外部作用域而非全局作用域的引用. def outter(): x = 1 def inner(): ...

  7. 『德不孤』Pytest框架 — 13、Pytest中Fixture装饰器(三)

    目录 9.ids参数说明 10.name参数说明 11.scope参数说明 (1)scope="function" (2)scope="class" (3)sc ...

  8. python 函数之装饰器,迭代器,生成器

    装饰器 了解一点:写代码要遵循开发封闭原则,虽然这个原则是面向对象开发,但也适用于函数式编程,简单的来说,就是已经实现的功能代码不允许被修改但 可以被扩展即: 封闭:已实现功能的代码块 开发:对扩张开 ...

  9. Python之路第一课Day4--随堂笔记(迭代生成装饰器)

    上节回顾: 1.集合 a.关系测试 b.去重 2.文件操作及编码 3.函数 4.局部变量和全局变量 上节回顾 本节课内容: 1.迭代器生成器 2.装饰器 3.json pickle数据序列化 4.软件 ...

随机推荐

  1. cygwin 安装包管理器 apt-cyg

    https://github.com/transcode-open/apt-cyg apt-cyg is a simple script. To install: lynx -source https ...

  2. Leetcode#1.Two Sum(两数之和)

    题目描述 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 15], ta ...

  3. js2wordcloud 词云包的使用

    js文件下载: https://github.com/liangbizhi/js2wordcloud/tree/master/ dist文件夹内 引用: <script src="** ...

  4. IMX6开发板学习烧写Linux-QT系统步骤做个笔记

    平台:迅为-i.MX6开发板  烧写系统:Linux-QT   <ignore_js_op>   Qt系统的烧写,是使用 MfgTool2 工具,只需要简单的配置下.   打开 “Mfgt ...

  5. POJ 1458 Common Subsequence 最长公共子序列

    题目大意:求两个字符串的最长公共子序列 题目思路:dp[i][j] 表示第一个字符串前i位 和 第二个字符串前j位的最长公共子序列 #include<stdio.h> #include&l ...

  6. Python笔记 【无序】 【三】

    #打开文件 os.open(file, flags[, mode]); file -- 要打开的文件 flags -- 该参数可以是以下选项,多个使用 "|" 隔开: os.O_R ...

  7. gprof使用介绍【转】

    转自:https://blog.csdn.net/linquidx/article/details/5916701 gprof 1.1      简介 gprof实际上只是一个用于读取profile结 ...

  8. proxyTable设置代理解决跨域问题

    应用场景:在不同域之间访问是比较常见,在本地调试访问远程服务器....这时就有域问题. 解决方案一:在config里面的index.js里面的proxyTable //这里理解成用‘/api'代替ta ...

  9. SSH远程联机Linux服务器简易安全设定

    分别可以由底下这三方面来进行: 1.服务器软件本身的设定强化:/etc/ssh/sshd_config 2.TCP wrapper 的使用:/etc/hosts.allow, /etc/hosts.d ...

  10. 通过python操作GeoLite2-City.mmdb库将nginx日志访问IP转换为城市写入数据库

    通过python操作GeoLite2-City.mmdb库将nginx日志写入数据库 # 创建存放nginx日志的表accesslog2 CREATE TABLE `accesslog2` ( `id ...