装饰器:
定义:
装饰器 本质是函数; 器代表函数;
功能:
装饰其他函数,就是为其他函数添加附加功能;
原则:
1.不能修改被装饰的函数的源代码
2.不能修改被装饰的函数的调用方式
装饰器对被装饰的函数是透明的。感受不到装饰器的存在。
实现装饰器知识储备:
1.函数即“变量”
一个简单的装饰器例子
import time
定义装饰器
def timmer(func):
def warrper(*args,**kwargs):
start_time=time.time()
func()
stop_time=time.time()
print("the func run time is %s"%(stop_time-start_time))
return warrper
@timmer
def test1():
time.sleep(3)
print("in the test1")
test1()举例说明:
def foo():
print("in the foo")
bar()
foo()
报错bar没有定义def bar():
print("in the bar")
def foo():
print("in the foo")
bar()
foo()
正常运行def foo():
print("in the foo")
bar()
def bar():
print("in the bar")
foo()
正常运行运行该例子的时候,先将定义的函数foo、bar依次存储到了内存;
然后在运行foo(),调用bar是在内存中存在的,所以不会报错。
def foo():
print("in the foo")
bar()
foo()
def bar():
print("in the bar")
foo()
会报错提示bar没有定义执行foo(),先将foo函数存储到内存,然后就运行foo;
而此时bar函数还没有定义写到内存中,找不到bar所以会报错。
总结:
定义一个函数就相当于将函数体赋值给函数名;
定义变量/函数 是先定义,再执行;
函数和变量一样都会被python内存回收机制回收;
所以:函数即“变量”
1.1匿名函数
#函数没有名字,下面给函数定义了一个变量名来引用;
niming = lambda x:x*3 print (niming(3))
2.高阶函数
a:把一个函数名当做实参给另外一个函数;
(在不修改被装饰函数源代码的情况下为其添加功能)
b:返回值中包含函数名;
(不修改函数的调用方式)
把函数当作一个实参传递给形参。
简单例子
def bar():
print("in the bar")
def test1(func):
print(func)
func()
test1(bar)
func()等于下面
func=bar
func()稍作改变
def bar():
time.sleep(0.3)
print("in the bar")
def test1(func):
start_time=time.time()
func()
stop_time=time.time()
print("the func run time is %s" %(stop_time-start_time))
test1(bar)总结:(在不修改被装饰函数源代码的情况下为其添加功能)
def bar():
time.sleep(0.3)
print("in the bar")
def test2(func):
print(func)
return func
运行1
print(test2(bar))
运行2
t = test2(bar)
t()
#运行3
bar=test2(bar)
bar()
bar是原函数总结:返回值中包含函数名; (不修改函数的调用方式)
写一个装饰器(高阶函数)
import time
def deco(func):
star_time= time.time()
func()
stop_time=time.time()
print("th func run time is %s"%(stop_time-star_time))
def deco(func):
star_time= time.time()
return func
stop_time=time.time()
print("th func run time is %s"%(stop_time-star_time))
def test1():
time.sleep(3)
print("in the test1")
def test2():
time.sleep(3)
print("in the test2")
deco(test1)
deco(test2)
test1=deco(test1)
test1()
test2=deco(test2)
test2()
结束时间没有运行;3.嵌套函数
高阶函数+嵌套函数= 装饰器
变化1
def timmer(func):
def deco():
star_time= time.time()
func()
stop_time=time.time()
print("th func run time is %s"%(stop_time-star_time))
return deco
def test1():
time.sleep(3)
print("in the test1")
def test2():
time.sleep(3)
print("in the test2")
test1=timmer(test1)
test1()
test2=timmer(test2)
test2()变化2 应用装饰器 嵌套函数
def timmer(func):
def deco():
star_time= time.time()
func()
stop_time=time.time()
print("th func run time is %s"%(stop_time-star_time))
return deco
@timmer #@timmer 就等于test1=timmer(test1) ;这就是装饰器
def test1():
time.sleep(3)
print("in the test1")
@timmer
def test2():
time.sleep(3)
print("in the test2")
test1()
test2()变化3 高级装饰器 可以满足日常90%的需求
def timmer(func):
def deco(*args,**kwargs):
star_time= time.time()
func(*args,**kwargs)
stop_time=time.time()
print("th func run time is %s"%(stop_time-star_time))
return deco
@timmer #@timmer 就等于test1=timmer(test1) ;这就是装饰器
def test1():
time.sleep(3)
print("in the test1")
@timmer
def test2(name,age):
time.sleep(3)
print("in the test2:name age")
test1()
test2("abc",123)终极高级版 decorator 就是装饰器的意思;
一、默认谁都可以访问三个网站
def index():
print("welcome to index page")
def home():
print("welcome to home page")
def bbs():
print("welcome to bbs page")
index()
home()
bbs()二、一部分home/bbs需要登录才能浏览
user,passwd="abc","123"
def auth(func):
def wrapper(*args,**kwargs):
username = input("Username:").strip()
password = input("Password:").strip()
if user == username and passwd == password:
print("\033[32;1m Auth is sucessed!\033[0m")
func(*args,**kwargs)
else:
print("\033[31;1m Auth is failed!\033[0m")
return wrapper
def index():
print("welcome to index page")
@auth
def home():
print("welcome to home page")
@auth
def bbs():
print("welcome to bbs page")
index()
home()
bbs()三、一部分home/bbs需要登录才能浏览
user,passwd="abc","123"
def auth(func):
def wrapper(*args,**kwargs):
username = input("Username:").strip()
password = input("Password:").strip()
if user == username and passwd == password:
print("\033[32;1m Auth is sucessed!\033[0m")
ret = func(*args,**kwargs) #from home ; 也可以直接return
print("-----after auth ")
return ret
else:
print("\033[31;1m Auth is failed!\033[0m")
return wrapper #而这里没有返回值;在上边return ret之后就有数据了
def index():
print("welcome to index page")
@auth
#当home有return结果的时候,用上边的无法获取到home return的结果;wrapper加一个return;
def home():
print("welcome to home page")
return "From home!"
@auth
def bbs():
print("welcome to bbs page")
index()
print(home()) #调用home相当于调用wrapper
bbs()四、home bbs两个目录,一部分可以直接访问,一部分需要登录才能浏览
以上案例是验证写死的,运维中有本地认证和ldap认证,认证方式有多种,需要以下完成;
home用本地认证,bbs用远程ldap认证;
import time
user,passwd="abc","123"
def auth(auth_type):
print(auth_type)
def outer_wrapper(func):
def wrapper(*args,**kwargs):
print("--wrapper func args:",*args,**kwargs)
if auth_type == "local":
username = input("Username:").strip()
password = input("Password:").strip()
if user == username and passwd == password:
print("\033[32;1m Auth is sucessed!\033[0m")
ret = func(*args, **kwargs) # from home,就是去运行home ; 也可以直接return
print("-----after auth ")
return ret
else:
print("\033[31;1m Auth is failed!\033[0m")
elif auth_type == "ldap":
print("no no no ldap!")
return wrapper # 而这里没有返回值;在上边return ret之后就有数据了
return outer_wrapper
def index():
print("welcome to index page")
#当home有return结果的时候,用上边的无法获取到home return的结果;wrapper加一个return;
@auth(auth_type="local") #home = auth()
def home():
print("welcome to home page")
return "From home!"
@auth(auth_type="ldap")
def bbs():
print("welcome to bbs page")
index()
print(home()) #调用home相当于调用wrapper
bbs()本文出自 “506554897” 博客,请务必保留此出处http://506554897.blog.51cto.com/2823970/1963710
原文:http://506554897.blog.51cto.com/2823970/1963710