装饰器
# 开发原则:开发封闭原则
# 装饰器的作用:在不改变原函数的调用函数下,在函数的前后添加功能。
# 装饰器的本质:闭包函数
import time

def timmer(f):  #func     #timmer就是一个装饰器函数
def inner():
start = time.time()
f() #用外部函数的变量f 是一个闭包 f()就是被装饰的函数
end = time.time()
print(end-start)
return inner #返回内部函数的名字(注意) @timmer #语法糖 @装饰器函数名,下面必须是被装饰的函数
def func(): #被装饰的函数
time.sleep(0.01)
print('大魔王法克儿')
# func=timmer(func) #有了语法糖这一句就不用写了
func() #相当于是inner()

args:接受*就是聚合,调用加*就是打散

*args:接受*就是聚合,调用加*就是打散
# *args:接受*就是聚合,调用加*就是打散
def func(*args): #站在形参的角度上,给变量加上*,就是组合所有传来的值
print(args) #(1, 2, 3, 4, 5)
print(*args) #1 2 3 4 5 func(1,2,3,4,5) #(1, 2, 3, 4, 5)

执行顺序

装饰器想当与一个中介,

wraps

def wahaha():
'''
一个函数
:return:
''' print('娃哈哈') print(wahaha.__name__) #wahaha
def wrapper(func):  #func=holidy
def inner(*args,**kwargs):
print('在被装饰函数之前执行')
ret = func(*args,**kwargs) #这个就是被装饰的函数
print('在被装饰函数之后执行')
return ret
return inner #inner = holidy @wrapper #holidy=wrapper(holidy) #调用wrapper,将holidy传进去,结果就是inner=holidy
def holidy(day):
print('放假%s天'% day)
return '返回的是这里'
ret = holidy(3) #inner()
print(ret)
from functools import wraps
def wrapper(func): #func=holidy
@wraps(func) #
def inner(*args,**kwargs):
print('在被装饰函数之前执行')
ret = func(*args,**kwargs) #这个就是被装饰的函数
print('在被装饰函数之后执行')
return ret
return inner #inner = holidy @wrapper #holidy=wrapper(holidy) #调用wrapper,将holidy传进去,结果就是inner=holidy
def holidy(day):
'''holidy._doc_出现的内容'''
print('放假%s天'% day)
return '返回的是这里' print(holidy.__name__)
print(holidy.__doc__) ret = holidy(3) #inner()
# print(ret)

作业

# 1、编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),
# 要求登录成功一次,后续的函数都无需再输入用户名和密码。
FALG = False #定义一个全局变量
def login(f):
def inner(*args,**kwargs):
global FALG
if FALG == True:
ret= f(*args,**kwargs)
return ret
else:
'''登录程序'''
username = input('请输入你的账号:')
password = input('请输入你的密码:')
li=[]
with open('The user data',mode='r+',encoding='utf-8') as f1:
for line in f1:
li.append(line) if username.strip() == li[0].strip() and password.strip() == li[1].strip():
FALG =True #全局变量=True
ret = f(*args, **kwargs)
return ret else:
print('用户名或密码错误,请重试') return inner @login
def shoplist_add():
print('增加一件物品')
return 1 def shoplist_del():
print('减少一件物品')
return 2 ret=shoplist_add()
ret=shoplist_del()
print(ret)
2、编写装饰器,为多个函数加上记录调用的功能,要求每次调用都将被调用的函数名称写入文件内
from functools import wraps
def log_record(f):
# @wraps(f)
def inner(*args,**kwargs):
print('--start---')
ret=f(*args,**kwargs)
print('--record---') with open('log_record',mode='a+',encoding='utf-8') as f1:
f1.write(f.__name__)
return ret return inner
@log_record
def fun1():
return 1
ret =fun1()
print(ret) @log_record
def fun2():
return 2 ret =fun2()
print(ret)
进阶
1、编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
import urllib
from urllib.request import urlopen def get(url):
code = urlopen(url).read()
print(code) ret=get('https://www.baidu.com/')
print(ret)
2、为题目1编写装饰器,实现缓存网页中内容的功能具体:实现下载的页面存放于文件中,如果文件中有值,就从文件中取,否则取下载存到文件中
import urllib
from urllib.request import urlopen
import os
def cache(f):
def inner(*args,**kwargs): if os.path.getsize('web_cache'): #如果有这个文件
with open('web_cache', mode='rb') as f1:
return f1.read()
else:
ret=f(*args,**kwargs)
with open('web_cache', mode='wb') as f1:
f1.write(b'@@@@@@'+ret)
return ret
return inner @cache
def get(url):
code = urlopen(url).read()
return code ret=get('https://www.baidu.com/') #第一次是从网站读出来的
print(ret)
ret=get('https://www.baidu.com/')#二次是从自己文件中读出
print(ret)
ret=get('https://www.baidu.com/')#三次是从自己文件中读出
print(ret)

装饰器的进阶(带参数的装饰器,多个装饰器装饰一个函数)

带参数的装饰器

#500个函数
import time
FALGE=True #用flag判断
def timmer_out(flag): #flag 只是形参,参数是谁无所谓 #最外边的一层只是为了把FALGE传进,其他的并没有改变
def timmer(func):
def inner(*args,**kwargs):
if flag: #如果flag 为true 则执行装饰器里计算时间的功能 start = time.time()
ret=func(*args,**kwargs)
end =time.time()
print(end - start)
return ret
else:
ret = func(*args, **kwargs)
return ret
return inner
return timmer #
@timmer_out(FALGE) #先执行 timmer_out(FALGE)-->返回timmer给timmer_out,此时其实就为@timmer
def wahaha():
time.sleep(0.1)
print('wahhhhhhhhh') @timmer_out(FALGE)
def xiaoyi():
time.sleep(0.2)
print('xiaoyiyiyiyi') #FLAGE=false #在这里可以控制FLAGE
wahaha()
xiaoyi()

多个装饰器装饰一个函数 (俄罗斯套娃,一层一层)
def wrapper1(func):
def inner():
print('wrapper1,before func')
func()
print('wrapper1,after func')
return inner def wrapper2(func):
def inner():
print('wrapper2,before func')
func()
print('wrapper2,after func')
return inner @wrapper2
@wrapper1 #靠近函数的这个装饰器先执行
def f():
print('in f') f()
#结果
'''
wrapper2
wrapper1
in f
wrapper1
wrapper2
'''

执行顺序:

ps:

def wrapper1(func):
def inner():
print('wrapper1,before func')
ret=func()
print('wrapper1,after func')
return ret
return inner def wrapper2(func):
def inner():
print('wrapper2,before func')
ret = func()
print('wrapper2,after func')
return ret return inner @wrapper2
@wrapper1 #靠近函数的这个装饰器先执行
def f():
print('in f')
return '哈哈哈'
print(f())
#结果(但是结果是从上至下,可以理解为套娃)
'''
wrapper2,before func
wrapper1,before func
in f
wrapper1,after func
wrapper2,after func
哈哈哈
''' # ps:
def f2():
print('in f')
return '哈哈哈'
print(f2())
'''
in f
哈哈哈
'''
用途:
记录用户的登录情况
计算这个函数的执行时间

												

python之路day12--装饰器的进阶的更多相关文章

  1. day12:装饰器的进阶

    1,三元运算符:变量 = 条件返回True的结果 if 条件 else 条件返回false的结果:必须要有结果:必须要有if和else,只能是简单的情况. 2,传参包起来,星号打散 def outer ...

  2. 小白的Python之路 day4 装饰器前奏

    装饰器前奏: 一.定义: 1.装饰器本质是函数,语法都是用def去定义的 (函数的目的:他需要完成特定的功能) 2.装饰器的功能:就是装饰其他函数(就是为其他函数添加附加功能) 二.原则: 1. 不能 ...

  3. python之路之装饰器

    一 装饰器进化之路1) import time def index(): start_time=time.time() time.sleep() print('welcome to index wor ...

  4. [Python之路] 使用装饰器给Web框架添加路由功能(静态、动态、伪静态URL)

    一.观察以下代码 以下来自 Python实现简易HTTP服务器与MINI WEB框架(利用WSGI实现服务器与框架解耦) 中的mini_frame最后版本的代码: import time def in ...

  5. 小白的Python之路 day4 装饰器高潮

    首先装饰器实现的条件: 高阶函数+嵌套函数 =>装饰器 1.首先,我们先定义一个高级函数,去装饰test1函数,得不到我们想要的操作方式 import time #定义高阶函数 def deco ...

  6. Python装饰器的进阶

    带参数的装饰器 示例一:Python自带的装饰器函数 from functools import wraps import time def Time(func1): @wraps(func1) de ...

  7. Python 装饰器(进阶篇)

    装饰器是什么呢? 我们先来打一个比方,我写了一个python的插件,提供给用户使用,但是在使用的过程中我添加了一些功能,可是又不希望用户改变调用的方式,那么该怎么办呢? 这个时候就用到了装饰器.装饰器 ...

  8. Python 入门之 Python三大器 之 装饰器

    Python 入门之 Python三大器 之 装饰器 1.开放封闭原则: (1)代码扩展进行开放 ​ 任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改.所以我们必须允许代 ...

  9. Python之路,Day12 - 那就做个堡垒机吧

    Python之路,Day12 - 那就做个堡垒机吧   本节内容 项目实战:运维堡垒机开发 前景介绍 到目前为止,很多公司对堡垒机依然不太感冒,其实是没有充分认识到堡垒机在IT管理中的重要作用的,很多 ...

随机推荐

  1. Spring MVC(一)五大核心组件和配置

    一,五大核心组件 1.DispatcherServlet 请求入口 2.HandlerMapping   请求派发,负责请求和控制器建立一一对应的关系 3.Controller   处理器 4.Mod ...

  2. Easyui 关闭jquery-easui tab标签页前触发事件

    关闭jquery-easui tab标签页前触发事件 by:授客 QQ:1033553122 测试环境 jquery-easyui-1.5.3 需求场景 点击父页面tab 页关闭按钮时,需要做判断,判 ...

  3. 章节十一、1-Junit介绍

    一.Junit是一个开源的测试框架,在selenium的jar包中,不需要单独安装和搭建环境 二.@BeforeClass:当在方法上加了这个注解的话,这个方法会在这个类的第一个test方法之前运行. ...

  4. 业务与IT技术

    最近听一个同事又再次提问关于业务比技术重要,是真的吗? 今天我们再来看一下.      一,什么是业务? 业务意指某种有目的的工作或工作项目.技术可以指人类对机器.硬件或人造器皿的运用,但它也可以包含 ...

  5. PM领导能力成熟度2级

    人生如戏,大幕拉开,他走上舞台,饰演PM一角. 从技术岗位迈向管理岗位的第一步,对大多数像他一样的新晋PM来说,并不轻松.技术知识与经验是他曾经的主要才能与成功基础,而从成熟度一级开始,身为管理者的他 ...

  6. Vue components Cannot read property '__ob__' of undefined

    在Vue开发过程中,子组件向父组件传值的过程中,函数时可以对应的触发的,但是当父组件要改变自己的属性的时候报错了. 具体的页面逻辑是这样的,父组件 子组件 点击了之后没有问题,子组件向父组件传值  t ...

  7. 【Linux】【MySQL】CentOS7、MySQL8.0.13 骚操作速查笔记——专治各种忘词水土不服

    1.前言 [Linux][MySQL]CentOS7安装最新版MySQL8.0.13(最新版MySQL从安装到运行) 专治各种忘词,各种水土不服. - -,就是一个健忘贵的速查表:(当然不包括SQL的 ...

  8. 测者的测试技术手册:分清Java的Override和Overload

    Java的Override和OverloadOverride重写:子类对父类的允许访问的方法实现过程重新编写,但是 不可改变返回值和入参.重弄写的规则: 参数列表必须完全与被重写方法的相同: 返回类型 ...

  9. WebSocket-java实践

    websocket  主要用于  前端页面hmtl/jsp 与 后端进行socket得连接. 本例简单实现:一但后端接收到数据或者根据某些规则主动发送数据,那么可以根据不同用户等区别,发送给某个登陆得 ...

  10. ORACLE 查询某表中的某个字段的类型,是否为空,是否有默认值等

    最近写的功能中有这样一个小功能,根据数据库查询此库中是否有某表,如果有,查询某表下面的某个字段的详细信息 其中一种是... select ATC.OWNER, atC.TABLE_NAME, ATC. ...