装饰器基础

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

在程序中工具就是函数

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

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

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

开闭原则:

    对修改关闭,对拓展开放

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

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

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

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
 
 
 
												

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. MeEclipse搭建SSH框架之———大体框架

    必备:MyEclipse软件,SSH需要的jar包,数据库,连接数据库的驱动jar包 先搭建大体框架,再加别的东西,要不都不知道哪里错了 一.新建web项目 MyEclipse左边右键--->N ...

  2. 添加 node mocha 测试模块

    1.mocha  支持TDD 和 BDD两种测试风格 2.引用assert模块  此模块是node的原生模块,实现断言的功能,作用是声明预期的结果必须满足 3.mocha测试用例中可以使用第三方测试库 ...

  3. 最全的jquery datatables api 使用详解

    学习可参考:http://www.guoxk.com/node/jquery-datatables http://yuemeiqing2008-163-com.iteye.com/blog/20069 ...

  4. Css - 浮动布局

    Css - 浮动布局 浮动布局 float 取值:left | right | none 利用float属性可设置元素的浮动,虽然浮动主要是应用于块元素,但行内元素其实也可以浮动,但行内元素本来就是一 ...

  5. 已安装nginx支持https配置 the "ssl" parameter requires ngx_http_ssl_module

    原文链接:https://blog.seosiwei.com/detail/28 nginx已安装,ssl模块未安装的解决方法: 如果需要在linux中编译自己的nginx服务器,请参照:https: ...

  6. exsi5.5以上版本支持虚拟机的二次虚拟化

    从存储里找到虚拟机的位置 下载并修改虚拟机的.vmx配置文件(记得做好备份) 打开<虚拟机名>.vmx文件,在末尾追加如下字段,保存退出. nce.enable = TRUE hyperv ...

  7. WindowsPE权威指南-PE文件头中的重定位表

    PE加载的过程 任何一个EXE程序会被分配4GB的内存空间,用户层处理低2G的内存,驱动处理高2G的内存. 1.双击EXE程序,操作系统开辟一个4GB的空间. 2.从ImageBase决定了加载后的基 ...

  8. ROI Pool和ROI Align

    这里说一下ROI Pool和ROI Align的区别: 一.ROI Pool层: 参考faster rcnn中的ROI Pool层,功能是将不同size的ROI区域映射到固定大小的feature ma ...

  9. Linux中设置别名

    作者:邓聪聪 查看别名: alias设置别名: 临时设置: alias show='ls -al' 永久生效: 修改 家目录/.bashrc [root@localhost ~]# cat .bash ...

  10. 《转》return *this和 return this有什么区别?

    别跟我说 return *this 表示返回当前对象,return this 表示返回当前对象的地址(指向当前对象的指针). 正确答案为:return *this 返回的是当前对象的克隆或者本身(若返 ...