day 13 装饰器
装饰器基础
装饰器的目的是为了给被装饰 对象,增加新功能,或者说增加某种能力
在程序中工具就是函数
如此一来,装饰器指的就是一个函数,被装饰着也是一个函数
总结;装饰器就是用一个函数去拓展另外一个已存在的函数的功能
拓展性是对于一个应用程序来说非常重要的能力,任何应用程序都需要拓展,于是出现了开闭原则
开闭原则:
对修改关闭,对拓展开放
不允许修改源代码以及调用方式
装饰器就是一种可以保证不修改源代码,也不修改调用方式,还能给函数添加新功能的方式
需求: 目前已有一个函数,其功能是从服务器下载一个文件,需求要为这个函数统计下载耗时
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 装饰器的更多相关文章
- Python基础:13装饰器
装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的应用有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同 ...
- Python Day 13 装饰器
阅读目录 内容回顾 函数嵌套的定义 global.nonlocal关键字 闭包及闭包的运用场景 开放封闭原则 装饰器 一个函数被多次装饰 ##内容回顾 1.函数对象:函数名 => 存放的是函 ...
- python 基础之第十天(闭包,装饰器,生成器,tarfile与hashlib模块使用)
局部变量与全局变量 局部变量:在函数里面定义的,只有当函数活动时才生效 全局变量:不在函数里面的 In [1]: x=10 In [2]: def bar(): ...: x=20 ...: prin ...
- 13、python中的函数(闭包与装饰器)
一.嵌套函数 函数的内部又再定义另一个函数,这个函数就叫嵌套函数,里面含函数就叫内部函数. 示例: 二.返回函数 函数可以接收函数对象作为参数,同理函数也能返回一个函数对象作为返回值. 示例: 返回函 ...
- 13.Python略有小成(装饰器,递归函数)
Python(装饰器,递归函数) 一.开放封闭原则 软件面世时,不可能把所有的功能都设计好,再未来的一两年功能会陆续上线,定期更新迭代,软件之前所用的源代码,函数里面的代码以及函数的调用方式一般不 ...
- 【0812 | Day 13】闭包函数/装饰器/迭代器
目录 闭包函数 无参装饰器 有参装饰器 迭代器 闭包函数 一.什么是闭包? 闭包指的是:函数内部函数对外部作用域而非全局作用域的引用. def outter(): x = 1 def inner(): ...
- 『德不孤』Pytest框架 — 13、Pytest中Fixture装饰器(三)
目录 9.ids参数说明 10.name参数说明 11.scope参数说明 (1)scope="function" (2)scope="class" (3)sc ...
- python 函数之装饰器,迭代器,生成器
装饰器 了解一点:写代码要遵循开发封闭原则,虽然这个原则是面向对象开发,但也适用于函数式编程,简单的来说,就是已经实现的功能代码不允许被修改但 可以被扩展即: 封闭:已实现功能的代码块 开发:对扩张开 ...
- Python之路第一课Day4--随堂笔记(迭代生成装饰器)
上节回顾: 1.集合 a.关系测试 b.去重 2.文件操作及编码 3.函数 4.局部变量和全局变量 上节回顾 本节课内容: 1.迭代器生成器 2.装饰器 3.json pickle数据序列化 4.软件 ...
随机推荐
- Linux基础学习【规则与安装】
一.主分区.扩展分区与逻辑分区的特性: 主分区与扩展分区最多可以有4个(硬盘的限制) 扩展分区最多只能有1个 逻辑分区是由扩展分区持续切割出来的分区 能够被格式化后作为数据访问的分区为主分区和逻辑分区 ...
- 玩转Google
前言: 网上浏览信息,用百度搜索的时候,第一页都是广告,真是槽心到极点,果断放弃百度,现在用谷歌是真舒服,用起一句话用好谷歌.用好搜索引擎.你可以打开世界的大门! 加入特殊字符搜索: | 同时搜索关键 ...
- SpringBoot - 添加定时任务
SpringBoot 添加定时任务 EXample1: import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spri ...
- 关于vue2.0 cnpm 镜像安装
前言:这几天安装vue环境一直报错,愁死我了,踩了好多坑,以前学的时候也安装成功了,后来很忙然后一直没顾上学vue,这么最近要学这个 在安装环境中平凡报错特此记笔记如下: 1.首先去下载node.js ...
- PTA L1题目合集(更新至2019.3)
L1-001 Hello World (5 分) 链接:https://pintia.cn/problem-sets/994805046380707840/problems/9948051471320 ...
- 记录一段QQ关于 UNIGUI 的Session 时间设定
记录一段QQ关于 UNIGUI 的Session 时间设定,来自[台中]cmj(31365722): [重點說明] 1.UniGUI的Session就是UniMainModule. 2.Sess ...
- linux shell 进阶篇、shell脚本编程-创建函数
使用函数 #!/bin/bash # testing the script function myfun { echo "This is an example of a function&q ...
- 用css解决table文字溢出控制td显示字数
场景: 最左边这栏我不行让他换行,怎么办呢? 下面是解决办法: table{ width:100px; table-layout:fixed;/* 只有定义了表格的布局算法为fixed,下面td的定义 ...
- 题解-POI2007 OSI-Axes of Symmetry
Problem bzoj1100 题意概要:给定一个简单多边形(不一定凸),求其对称轴数量 数据组数\(\leq 10\),多边形点数\(\leq 10^5\) Solution 这题算是跨界算法的经 ...
- Nginx和apache服务器中php运行方式
PHP5的CGI方式的一大优势是内置了FastCGI的支持,只需指明绑定的地址和端口参数便可以以FastCGI的方式运行,如下: php-cgi -b 127.0.0.1:9000 配置Nginx的P ...