一、闭包:内部函数包含对外部作用域而非全局作用于的引用
1、闭包的意义与应用:返回的函数对象不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得该函数无论在何处调用,优先使,用自己外层包裹的作用域。应用领域:延迟计算
from urllib.request import urlopen
# def index(url):
# def get():
# return urlopen(url).read()
# return get
# baidu=index('http://www.baidu.com')
# print(baidu().decode('utf-8'))
二、装饰器:属于闭包函数的一种应用场景,对修改封闭,对扩展开放。本身可以是任意可调用对象,被装饰者也可以是任意调用对象,
装饰器的原则:1、不修改被装饰对象的源代码 2、不修改被装饰对象的调用方式
装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能
1、无参装饰器
# import time
# def timmer(func):
# def wrapper(*args,**kwargs):
# start_time=time.time()
# res=func(*args,**kwargs)
# stop_time=time.time()
# print('run time is %s' %(stop_time-start_time))
# return res
# return wrapper
# @timmer
# def foo():
# time.sleep(3)
# print('from foo')
# foo()
#
# answer
# from foo
# run time is 3.0008201599121094
2、有参装饰器
def auth(driver='file'):
# def auth2(func):
# def wrapper(*args,**kwargs):
# name=input('user:')
# pwd=input('pwd:')
# if driver=='file':
# if name=='Heling' and pwd=='kaixin':
# print('login successful')
# res=func(*args,**kwargs)
# return res
# elif driver=='ldap':
# print('ldap')
# return wrapper
# return auth2
# @auth(driver='file')
# def foo(name):
# print(name)
#
# foo('Heling')
#
# answer:
# user:Heling
# pwd:kaixin
# login successful
# Heling
3、装饰器语法:被装饰的正上方,单独一行
@deco1
@deco2
@deco3
def foo():
pass
foo=deco1(deco2(deco3(foo)))
4、装饰器补充
from functools import wraps
# def deco(func):
# @wraps(func)
# def wrapper(*args,**kwargs):
# return func(*args,**kwargs)
# return wrapper
#
# @deco
# def index():
# print('from index')
#
# print(index.__doc__)
None
# 编写函数,(函数执行的时间是随机的)
# 二:编写装饰器,为函数加上统计时间的功能
# 三:编写装饰器,为函数加上认证的功能
#
# 四:编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
# 注意:从文件中读出字符串形式的字典,可以用eval('{"name":"egon","password":"123"}')转成字典格式
#
# 五:编写装饰器,为多个函数加上认证功能,要求登录成功一次,在超时时间内无需重复登录,超过了超时时间,则必须重新登录
#
# 六:编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
#
# 七:为题目五编写装饰器,实现缓存网页内容的功能:
# 具体:实现下载的页面存放于文件中,如果文件内有值(文件大小不为0),就优先从文件中读取网页内容,否则,就去下载,然后存到文件中
#
# 扩展功能:用户可以选择缓存介质/缓存引擎,针对不同的url,缓存到不同的文件中
#
# 八:还记得我们用函数对象的概念,制作一个函数字典的操作吗,来来来,我们有更高大上的做法,在文件开头声明一个空字典,然后在每个函数前加上装饰器,完成自动添加到字典的操作
#
# 九 编写日志装饰器,实现功能如:一旦函数f1执行,则将消息2017-07-21 11:12:11 f1 run写入到日志文件中,日志文件路径可以指定
# 注意:时间格式的获取
# import time
# time.strftime('%Y-%m-%d %X')
浙公网安备 33010602011771号