装饰器基础

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

在程序中工具就是函数

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

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

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

开闭原则:

    对修改关闭,对拓展开放

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

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

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

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. PKUSC2018游记

    由于菜鸡DreamlessDreams还需要准备中考的原因....这篇游记拖到今天才发. Day0:出发+报道                                              ...

  2. Java8新特性(待更新...)

    一.Lambda表达式 二.接口的默认方法与静态方法 三.方法引用 四.重复注解 五.扩展注解的支持 六.Optional 七.Stream 八.Date/Time API (JSR 310) 九.J ...

  3. Python笔记(三)继承和多态、动态语言

    一.继承 先定义一个A类 class A(object): def fun(self): print "Run A fun()" 在定义一个B类 class B(A): pass ...

  4. windows下flazr对rtmp视频流进行压力测试(批量直播测试)

    flazr-0.7-RC2下载地址:百度网盘 提取码:nu05 简述:通过推流软件推送摄像头视频流到nginx流媒体服务器,获取nginx流媒体服务器上的视频流,在windows下使用flazr软件进 ...

  5. Java strictfp有什么作用

  6. google 变量命名规则简要记录

    1.文件命名规则 好的文件名命名可以很清晰的看出这个文件将要承载的内容,Google给出的规则为:文件名要全部小写, 可以包含下划线 (_) 或连字符 (-). 按项目约定来, 例如:cmd_save ...

  7. [转] 多核CPU 查看进程分配的CPU具体核id

    转自:https://linux.cn/article-6307-1.html ps. 方法二简明直接 done! 当你在 多核 NUMA 处理器上运行需要较高性能的 HPC(高性能计算)程序或非常消 ...

  8. Python换行符问题:\r\n还是\n?

    今天写一个Python脚本去读取一个txt文件时,发现一个很有趣的现象: 如果这个文件是用atom编辑器写的,发现换行符是'\r'.这样一来去逐行读取数据就失效了,因为用open函数 去打开该文件re ...

  9. CString/string 区别及其转化

    CString/string 区别及其转化 利用MFC进行编程时,我们从对话框中利用GetWindowText得到的字符串是CString类型,CString是属于MFC的类.而一些标准C/C++库函 ...

  10. Flask组件

    组件踩坑记录 : 先注册组件在使用配置(...) flask-script Flask Script扩展提供向Flask插入外部脚本的功能,包括运行一个开发用的服务器,一个定制的Python shel ...