闭包:内部函数的参数调用外部函数的参数就是一个闭包
def A():
a = 1
def B():
print(a)
return B #
a = A()
a()
这样的一个函数就构成了闭包函数
例子说明去理解闭包和装饰器之间的关系
from functools import wraps
def wrapper(f):
@wraps(f)
def inner(*args, **kwargs):
ret = f(*args, **kwargs)
return ret
return inner
@wrapper # func = wrapper(func) wrapper函数
def func(a, b, c, d=1234):
print(a, b, c, d)
return "Hello World"
-------------------------------------结果----------------------------------------
print(func.__name__)
if func.__doc__:
print("True")
--------------------------------------------------------------------------------
*args 是接受任意数据类型
**kwargs是接受位置参数 比如a=1 ,b =4
@wrapper其实就是去执行wrapper函数把func当成参数去执行,func进入wrapper之后,本质上就是执行了inner函数。
-------------------------------------------------------------------------------------
加深小练习:
编写装饰器,为多个函数加上认证功能(用户的账号密码来源于文件)要求登录成功一次 后续的函数都无需输入用户名和密码
FLAG = False
def login(f):
def inner(*args, **kwargs):
global FLAG
if FLAG:
ret = f(*args, **kwargs)
return ret
else:
username = input("username:")
password = input("password:")
if username == 'admin' and password == '1234':
FLAG = True
ret = f(*args, **kwargs)
return ret
else:
print("错误!")
return inner
@login
def shoplist_add():
print("add")
@login
def shoplist_delete():
print("delete")
-----------------------------------------------------------------------------------
# 编写装饰器 为多个函数加上记录调用功能,要求每次调用函数都将被调用的函数名称写入文件
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 # shoplist_add = log(shoplist_add)
def shoplist_add():
print("add")
@log
def shoplist_delete():
print("delete")
shoplist_delete()
shoplist_add()
-------------------------------------------------------------------------------------
#.1编写下载网页内容的函数 要求功能是: 用户传入一个url 函数返回下载页面的结果2.为题目1编写装饰器 实现缓存网页中欧内容的功能
具体 实现下载的页面存放与文件中 如果文件内有值(文件大小不为0)就优先从文件中读取网页内容 否则就去下载'''
import os
from urllib.request import urlopen
def cache(func):
def inner(*args, **kwargs):
if os.path.getsize('web_Cache'):
with open('web_Cache','rb')as f:
return f.read()
ret = func(*args, **kwargs)
with open('web_Cache','wb') as f:
f.write(b'*********' + ret)
return ret
return inner
@cache # get = cache(get)
def get(url):#inner
code = urlopen(url).read()
return code
# {'网址':"文件名"}
url ='https://baike.baidu.com/item/%E5%A4%A7%E4%BD%AC/33459'
ret = get(url)
print(ret)
ret = get(url)
print(ret)
python装饰器进阶代码:
import time
Flag =True
def contrl_flag(flag):
def timer(func):
def inner(*args, **kwargs):
if flag:
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 timer
@contrl_flag(Flag)
def test1():# @timer = timer(test1)
time.sleep(0.1)
print("test1")
@contrl_flag(Flag)
def test2():
time.sleep(0.1)
print("test2")
test1()
test2()