day12:装饰器的进阶
1,三元运算符:变量 = 条件返回True的结果 if 条件 else 条件返回false的结果;必须要有结果;必须要有if和else,只能是简单的情况。
2,传参包起来,星号打散
def outer(*args):
print(args)
print(*args) outer(1,2,3,4) #==> outer(*(1,2,3,4)) *打散,传参的时候,默认包起来包成一个元祖,拿出来用的时候,加*号打散 outer(*[1,2,3,4])
3,print为何可以接收各种参数,因为默认里面参数加了*args,内置函数是用C语言写的
4,昨天作业一
# 1.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),
# 要求登录成功一次,后续的函数都无需再输入用户名和密码 # 自己的版本
FLAG = False
def wrapper(func):
def inner(*args,**kwargs):
global FLAG
if FLAG == False: # not FLAG
usrname = input("please input username:")
li = []
with open("file.txt",encoding="utf-8") as f1:
for line in f1:
li.append(line.strip())
if li[0] == usrname :
pwd = input("please input password:")
if li[1] == pwd:
print("登录成功")
FLAG = True
else:
FLAG = False
print("登录失败")
return
else:
FLAG = False
print("登录失败")
return ret = func(*args,**kwargs)
return ret
return inner @wrapper
def func():
print("in func") @wrapper
def func1():
print("in func1") @wrapper
def func2():
print("in func2") func()
func1()
func2()
# 可以看到这儿只认证了一次
运行结果:
please input username:lisa
please input password:123
登录成功
in func
in func1
in func2
1.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),
# 要求登录成功一次,后续的函数都无需再输入用户名和密码 # 老师的版本
# FLAG = False
# def login(func):
# def inner(*args,**kwargs):
# global FLAG
# '''登录程序'''
# if FLAG:
# ret = func(*args, **kwargs) # func是被装饰的函数
# return ret
# else:
# username = input('username : ')
# password = input('password : ')
# if username == 'boss_gold' and password == '22222':
# FLAG = True
# ret = func(*args,**kwargs) #func是被装饰的函数
# return ret
# else:
# print('登录失败')
# return inner
#
# @login
# def shoplist_add():
# print('增加一件物品')
#
# @login
# def shoplist_del():
# print('删除一件物品')
#
# shoplist_add()
# shoplist_del()
5,昨天作业二:
# 2.编写装饰器,为多个函数加上记录调用功能,要求每次调用函数都将被调用的函数名称写入文件
# 自己的版本
def wrapper(func):
def inner(*args,**kwargs):
funcname = func.__name__
with open("func_call_record.txt","a+",encoding="utf-8") as f1:
f1.write(funcname+"\n")
ret = func(*args,**kwargs)
return ret
return inner @wrapper
def func():
pass @wrapper
def func1():
pass @wrapper
def func2():
pass func1()
func2()
func()
func1()
# 2.编写装饰器,为多个函数加上记录调用功能,要求每次调用函数都将被调用的函数名称写入文件
# 老师的版本
def log(func):
def inner(*args,**kwargs):
with open('log','a',encoding='utf-8') as f:
f.write(func.__name__+'\n')
ret = func(*args,**kwargs)
return ret
return inner @log
def shoplist_add():
print('增加一件物品') @log
def shoplist_del():
print('删除一件物品') shoplist_add()
shoplist_del()
shoplist_del()
shoplist_del()
shoplist_del()
shoplist_del()
6,昨天作业三:
# 进阶作业(选做):
# 1.编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
# 2.为题目1编写装饰器,实现缓存网页内容的功能:
# 具体:实现下载的页面存放于文件中,如果文件内有值(文件大小不为0),就优先从文件中读取网页内容,否则,就去下载,然后存到文件中 # 老师的版本
from urllib.request import urlopen
import os def cache(func):
def inner(*args,**kwargs):
if os.path.getsize("web_cache.txt"):
with open("web_cache.txt","rb") as f:
return f.read()
ret = func(*args,**kwargs)
with open("web_cache.txt",'wb') as f:
f.write(b"******"+ret)
return ret return inner @cache
def get_code(url):
code =urlopen(url).read()
return code code = get_code('http://www.baidu.com') # 路径要给全
print(code)
code = get_code('http://www.baidu.com') # 路径要给全
print(code)
code = get_code('http://www.baidu.com') # 路径要给全
print(code)
7,被装饰之后,保留原函数的各种属性
def wrapper(f):
def inner(*args,**kwargs):
'''
我是inner函数
:return:
'''
ret = f(*args,**kwargs)
return ret
return inner @wrapper
def func():
'''
我是被修饰的函数func
:return:
''' pass print(func.__name__)
print(func.__doc__) 运行结果:
inner 我是inner函数
:return:
8,从上一步看出,打印出来的信息都是和inner相关的,这并不是我想要的,我想要的是被修饰函数相关的,怎么办呢?
from functools import wraps def wrapper(f):
@wraps(f)
def inner(*args,**kwargs):
'''
我是inner函数
:return:
'''
ret = f(*args,**kwargs)
return ret
return inner @wrapper
def func():
'''
我是被修饰的函数func
:return:
''' pass print(func.__name__)
print(func.__doc__) # 看出来代码哪里变化了吗?
运行结果:
func 我是被修饰的函数func
:return:
9,带参数的装饰器,其实是又加了一层,三层其实是最多的了,作用就一个,传递进去一个或者多个参数,然后返回内层函数。
import time FLAG = False
def timer_off(flag):
def timer(f):
def inner():
if flag:
starttime = time.time()
ret = f()
endtime = time.time()
duration = endtime - starttime
print(duration)
return ret
else:
ret = f()
return ret
return inner
return timer FLAG = True
@timer_off(FLAG) #timer_off(FLAG) ==timer @time == func=timer(func) 也就是inner
def func():
time.sleep(0.1)
print("i am func") func()
10,老师推荐了两本书:《Python核心编程》第二版和《流畅的Python》 先看第一本,第二本比较讲的比较深
11,多个装饰器装饰一个函数,弄清楚是谁装饰了谁,执行顺序
def wrapper1(f):
def inner1():
print("before inner1")
ret = f()
print("after inner1")
return ret
return inner1 def wrapper2(f):
def inner2():
print("before inner2")
ret = f()
print("after inner2")
return ret
return inner2 @wrapper2
@wrapper1
def func():
print("i am func") func()
运行结果:
before inner2
before inner1
i am func
after inner1
after inner2
def wrapper1(f):
def inner1():
print("before inner1")
ret = f()
print("after inner1")
return ret
return inner1 def wrapper2(f):
def inner2():
print("before inner2")
ret = f()
print("after inner2")
return ret
return inner2 @wrapper1
@wrapper2
def func():
print("i am func") func()
运行结果:
before inner1
before inner2
i am func
after inner2
after inner
day12:装饰器的进阶的更多相关文章
- python基础(8)-装饰器函数&进阶
从小例子进入装饰器 统计一个函数执行耗时 原始版本 import time # time模块有提供时间相关函数 def do_something(): print("do_something ...
- 洗礼灵魂,修炼python(30)--装饰器(2)—>装饰器总结+进阶使用
在上一篇博文的经典案例中,我想你应该对装饰器有很好的了解了,不过光有那些还不够真的,还需要总结和进阶一下,所以本篇博文解析装饰器进阶. 装饰器 1.什么是装饰器? 个人理解:装饰器又叫语法糖,指的是对 ...
- python之路第五篇之装饰器:(进阶篇)
装饰器: 学前必备知识: def f1(): print "f1" f1() #表示函数执行 f1 #表示函数,指向内存地址 f1 = lambda x: x + 1 f1() # ...
- Python装饰器的进阶
带参数的装饰器 示例一:Python自带的装饰器函数 from functools import wraps import time def Time(func1): @wraps(func1) de ...
- day12 装饰器的模版
1.什么是装饰器 装饰器指的是为被装饰对象(别人)添加新功能的工具 装饰器本身可以是任意可调用对象 被装饰器对象也可以是任意可调用对象 2.为何要用装饰器 开放封闭原则:指的是对修改封闭,对扩展开放 ...
- Python 装饰器(进阶篇)
装饰器是什么呢? 我们先来打一个比方,我写了一个python的插件,提供给用户使用,但是在使用的过程中我添加了一些功能,可是又不希望用户改变调用的方式,那么该怎么办呢? 这个时候就用到了装饰器.装饰器 ...
- 总结day12 ----装饰器
一,什么是装饰器? 装饰器本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象. 装饰器的应用场景:比如插入日志,性能测试,事 ...
- Day12装饰器
1.装饰器 什么是装饰器:装饰器指的是为被装饰对象添加新功能的工具 装饰器本身可以是任意调用对象 被装饰对象本身也可以是任意可调用对象 2.为何要用装饰器: 开放封闭原则: ①对修改源代码和调用方式是 ...
- python之装饰器的进阶
一.带参数的装饰器 (必须会) 针对不同的app的验证,比如:天猫和天猫超市,京东商城和京东超市 def wrapper_out(n): print(n) def wrapper(f): def in ...
随机推荐
- struts2:struts.properties配置文件介绍及常量加载顺序
1. 背景 struts2框架中有两个核心配置文件,其中struts.xml文件主要负责管理应用中的action映射,以及该action包含的result定义等.除此之外,struts2框架还包括一个 ...
- 运行第一个Docker容器-Docker for Web Developers(1)
1. Docker介绍 Docker由dotCloud公司发起的一个内部项目,后来Docker火了,dotCloud公司改名为Docker了: Docker使用了Go语言开发,基于 Linux 内核的 ...
- 物联网架构成长之路(15)-Jenkins部署SpringBoot
1.前言 现在慢慢也在负责一些工作了.这段时间有空,就多了解了解软件多人开发的一些知识.以前项目都是我一个人做的,从数据库设计到后端再到前端,全部放在一个war包丢到tomcat里面然后运行,利用to ...
- Python3实现Win10桌面背景自动切换
[本文出自天外归云的博客园] 得空写了个自动切换桌面背景图片的小程序.再不写python就要扔键盘了,对vue还有那么一点好感,天天php真是有够烦. 准备工作 准备个文件夹放在桌面上,平时看到什么高 ...
- Android 实时录音和回放,边录音边播放 (KTV回音效果)
上一篇介绍了如何使用Mediarecorder来录音,以及播放录音.不过并没有达到我的目的,一边录音一边播放.今天就讲解一下如何一边录音一边播放.使用AndioRecord录音和使用AudioTrac ...
- 【css】css 中文字体 unicode 对照表
css 中文字体可以用 unicode 格式来表示,比如“宋体”可以用 \5B8B\4F53 来表示.具体参考下表: 中文名 英文名 unicode 宋体 SimSun \5B8B\4F53 黑体 S ...
- easyui-combox(tagbox) 多选操作 显示为tagbox
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Android studio 怎么使用单元测试(不需要device)
关于单元测试的使用,写代码过程中有时候需要检测下代码逻辑的可行性与正确性,又不想通过设备运行,那么就可以通过单元测试跑下代码~ 1.首先建立一个Android studio的Android项目: 2. ...
- WampServer自己DIY添加apache、php、mysql版本
下载自己需要的apache版本. 下载地址: http://httpd.apache.org/download.cgi http://www.apachelounge.com/download/ 解压 ...
- 【netcore基础】.Net core使用swagger自动生成开发文档
之前写过一篇 .Net 版本的博客 https://www.cnblogs.com/jhli/p/8317566.html 现在只不过用了 netcore 之后的版本,其实差不多 netcore版本的 ...