首页 > 代码库 > python之-- 装饰器

python之-- 装饰器

高阶函数+嵌套函数 == 装饰器
什么是装饰器: 其实也是一个函数。
功能:为其他的函数添加附加功能
原则:不能修改被装饰的函数的源代码和调用方式

学习装饰器前首先要明白以下3条事项:
1:函数 即 “变量” (什么意思呢,就是说我们定义的一个函数,其中函数名就是一个变量,函数体就是存于内存的数据)。
def foo(): #函数名就相当于变量
print(‘test‘) #函数体就相当于内容
类似于:x(变量) = 1(内容)
内容实际存储于内存,变量相当于门牌号(映射内存内容)。
实例
def foo():
print(‘in the foo‘)
bar()
def bar():
print(‘in the bar‘)
foo()
   2:高阶函数
条件1:把一个函数名当作实参传给另一个函数(在不修改被装饰函数源码的情况下为其添加附加功能)
举例:当调用执行函数fun1时候,会把bar函数当作实参传入,在fun1函数内对形参进行执行fun() -> bar ->bar()
def bar():
print(‘in the bar‘)
def fun1(fun):
print(‘start) #进行装饰
fun() #执行的核心函数
print(‘end‘) #进行装饰
fun1(bar)
   条件2:函数的返回值中包含n>0个函数。(不修改函数的调用方式)
  举例:
  def bar():
  time.sleep(3)
  print(‘in the bar‘)
  def test2(func):
  print(func)
  return func
  bar = test2(bar)
  bar() #这里就是源函数被修饰后,再次调用返回被修饰后的结果
   3:嵌套函数:一个函数体内创建另一个函数,最外层函数相当于全局变量,函数内部的所有函数都相当于局部变量,只在局部作用域有效。
举例:
def foo():#这里相当于全局变量
print(‘in the foo‘)
def bar(): # 这里相当于局部变量,只在局部作用域有效。
print(‘in the bar‘)
bar() #执行局部变量
foo() #执行函数调用
  装饰器实例1:先加载timer函数体到内存,然后在@timer相当于将test1函数作为实参传递给timer函数,最后调用test1()函数,就相当于执行timer函数内的warpper函数,将内部执行结果返回         给test1
技术分享
 1 def timer(func):  # func = test1
 2     def warpper():
 3         start_time = time.time()
 4         func()
 5         end_time = time.time()
 6         print(the function time is %s %(stop_time-start_time)
 7     return warpper()
 8 @timer  #test1=timer(test1)
 9 def test1():
10     time.sleep(3)
11     print(in the test)
12 test1()  #这里test1就相当于在执行warpper函数
View Code
装饰器实例2带参数
技术分享
 1 import time
 2 def timer(fun): # 传入每个被装饰的函数名
 3     def bar(*args,**kwargs): # 传入每个被装饰的函数参数
 4         start = time.time()
 5         fun(*args,**kwargs)
 6         end = time.time()
 7         print(time:%s % (end-start))
 8     return bar
 9 @timer
10 def test1():
11     time.sleep(1)
12     print(in the test1)
13 @timer
14 def test2(name,age):
15     print(test2:,name,age)
16 test1()
17 test2(jeck,age=22)
View Code
装饰器-补充:如何返回被装饰的函数的return值
技术分享
 1 user,passwd = jeck,abc123
 2 def auth(func):
 3     def warpper(*args,**kwargs):
 4         username = input(username)
 5         password = input(password)
 6         if username == user and password == passwd:
 7                 print(user has passwd authentication)
 8                 mess = func(*args,**kwargs) # 这里返回func函数的return值
 9                 return mess  # 这里将mess的值返回给warpper
10         else:
11                 exit(error password)
12         return warpper  # 返回warpper值,包含mess的
13     
14 def index():
15     print(welcome to index page)
16 @auth
17 def home():
18     print(welcome to home page)
19     return from home  #这里的return如何通过装饰器返回
20 @auth
21 def bbs():
22         print(welcome to bbs page)
23 index()
24 print(home()) #这里要用print打印使用return返回的值
25 bbs()        
View Code
装饰器--高级版,这里让上面例子里home用普通验证,bbs用ldap验证
技术分享
 1 import time
 2 name,pwd = jeck,123
 3 def auth_type(auth_type):#认证模式参数传入
 4     def auth(fun):
 5         def warpper(*args,**kwargs):
 6             if auth_type == local: # 根据认证模式执行函数
 7                 name = input(name:)
 8                 passwd = input(passwd:)
 9                 if name == name and passwd == pwd:
10                     print(welcome logname :%s % name)
11                     content = fun(*args,**kwargs)
12                     return content
13             elif auth_type == ldap: #根据认证模式执行函数
14                 print(ldap)
15                 content = fun(*args,**kwargs)
16                 return content
17         return warpper
18     return auth
19 def index():
20     print(welcome to index page)
21 @auth_type(auth_type = local)# 增加认证模式的选择
22 def home():
23     print(welcome to home page)
24     return from home  #需要获取这里的return返回
25 @auth_type(auth_type = ldap) # 增加认证模式的选择
26 def bbs(name,age):
27     print(welcome to bbs page)
28     return name,age
29 index()
30 print(home())
31 print(bbs(bard,age=22))
View Code

 

python之-- 装饰器