str pri 函数的调用方式 clas ldap log 背景 亮显
一、定义
装饰器本质是函数,装饰其他函数,就是为其它函数添加附加功能
二、装饰器原则
1.不能修改被装饰的函数的源代码
2.不能修改被装饰的函数的调用方式
三、实现装饰器的必要知识
1.函数即是变量
- # def foo():
- # print("in the foo")
- # bar() #bar未定义
- # foo()
- # def bar():
- # print("int the bar")
- # def foo():
- # print("in the foo")
- # bar()
- # foo()
- # def foo():
- # print("in the foo")
- # bar()
- # def bar():
- # print("int the bar")
- # foo()
- def foo():
- print("in the foo")
- bar()
- foo()
- def bar(): #在调用后定义不会执行
- print("int the bar")
2.高阶函数(高阶函数的两种表达方式)
2.1把一个函数名当作实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)
- import time
- def bar():
- time.sleep(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)
2.2返回值中包含函数名
- import time
- def bar():
- time.sleep(3)
- print("in the bar")
- def test2(func):
- print(func)
- return func#返回为内存地址
- #print(test2(bar))
- # t=test2(bar)
- # t() #run bar
- bar=test2(bar)
- bar() #返回的内存地址加上()就可以执行
3.嵌套函数
- x=0
- def a():
- x=1
- def b():
- x=2
- def c():
- x=3
- print(x)
- c()
- b() #此处如果不执行b(),那么函数相当于什么都没干,因为没有print
- a()
四、装饰器=高阶函数+嵌套函数
- import time
- def timer(func): #timer(test) func=test
- def deco():
- start_time = time.time()
- func() #此处运行被装饰函数test
- stop_time = time.time()
- print("func run time is %s" %(stop_time-start_time))
- return deco #返回deco的内存地址
- @timer #相当于timer=timer(test),装饰器永远放在被装饰的函数前
- def test():
- time.sleep(3)
- print("this is test")
- test()
五、如果装饰器的函数中包含参数
- import time
- def timer(func):
- def deco(*args,**kwargs): #*args,**kwargs代表参数不确定的意思
- start_time=time.time()
- func(*args,**kwargs)
- stop_time=time.time()
- print("in the run time is %s" %(stop_time-start_time))
- return deco
- @timer # test2 = timer(test2) = deco test2(name) = deco(name)
- def test2(age,name,job):
- time.sleep(1)
- print("test2:",age,name,job)
- test2(23,"Irlo","seller")
六、装饰器的使用实例
假设为网页添加登陆验证
- user,pasd = "Irlo","12345"
- def auth(auth_type):
- print("auth func is",auth_type)
- def type(func):
- def wrapper():
- if auth_type == "local":
- username = input("username:").strip() #strip移除字符串首尾指定的字符(默认为空格)
- password = input("password:").strip()
- if user==username and pasd==password:
- print("\033[1;32;1mauthority of account\033[0m") #高亮显示的格式(\033[显示方式;前景色;背景色m)
- res=func() #将结果赋值给一个变量才能在之后调用home有结果
- print("after authentication")
- return res #如果不返回,相当于执行完就结束了,没有返回值是一个空值
- else:
- print(" invalid username or password ")
- elif auth_type == "ldap":
- print("I just know local,fuck off")
- return wrapper
- return type
- def index():
- print("welcome to index page")
- @auth(auth_type = "local")
- 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
- home()
- bbs()
Python 3 学习笔记(六)----装饰器
来源: http://www.bubuko.com/infodetail-2297191.html