装饰器
装饰器:
1定义:本质是函数,装饰其他函数,为其他函数添加附加功能
2原则:a.不能修改被装饰的函数源代码,有可能会导致其他问题
b.不能修改被装饰函数的调用方式
实现装饰器需要的知识点:
1知道装饰器其实就是函数
2高阶函数+嵌套函数=》装饰器
只要在调用之前存在与内存中的函数,就可以调用
def test1(): print('in the 1') #a先把这段字符串放到内存中 test2() # def test2(): print('in the 2')#b先把这段字符串放到内存中,与#a都是在调用前进行的,存起来以后再进行调用,因此不会报错 test1() 打印结果: in the 1 in the 2
高阶函数:a.把一个函数名当做实参传给另外一个函数(见有点用版,在不改源代码的前提下增加功能,但是修改了调用方式)
b.返回值包含函数名(不修改函数的调用方式)
闲的蛋疼没卵用版:
def test1(): print('in the 1') def test2(func): print(func) #把test1赋值给func,打印test1的内存地址 func() #把test1赋值给了func,此行等于test1() test2(test1) 打印结果: <function test1 at 0x000001E373D97F28> in the 1
有点用版(函数名做实参传给另外一个函数):
import time def test1(): time.sleep(2) print('in the 1') def test2(func): time_start=time.time() func() #运行test1 time_stop=time.time() print('test1 start time is %s'%(time_start)) print('test1 stop time is %s'%(time_stop)) print('test1 running time is %s'%(time_stop-time_start)) test2(test1) #修改了调用方式 运行结果: in the 1 test1 start time is 1517248119.7000022 test1 stop time is 1517248121.7005115 test1 running time is 2.000509262084961
嵌套函数:
def foo(): print('in the foo') def bar(): #函数中再用def定义函数才叫嵌套函数 print('in the bar') bar() foo() 打印结果: in the foo in the bar
局部作用域和全局作用域的访问顺序:
x=0 def grandpa(): x=1 def father(): x=2 def son(): x=3 print(x) son() father() grandpa() 打印结果: 3
铺垫结束,进入正题:
装饰器
#! /usr/bin/env python # -*- coding: utf-8 -*- # __author__ = "Deakin" # Email: 469792427@qq.com # Date: 2018/2/1 import time def timer(func): #timer(test1) func=test1 def deco(*args,**kwargs): #加了args和kargs可以对有参数和无参数进行装饰 start_time=time.time() func(*args,**kwargs) #run test1() stop_time=time.time() print('func run time is %s'%(stop_time-start_time)) return deco @timer # 语法糖 相当于test1=timer(test1),给谁加装饰器就写在谁前面 def test1(): time.sleep(1) print('in the test1') @timer def test2(name,age): print('test2:',name,age) #test1=timer(test1) #run deco() test1() test2("deakin",28) 打印结果: in the test1 func run time is 1.0002985000610352 test2: deakin 28 func run time is 0.0
终极版:添加不同的登录方式
#! /usr/bin/env python # -*- coding: utf-8 -*- # __author__ = "Deakin" # Email: 469792427@qq.com # Date: 2018/2/9 user,passwd='deakin','123456' def auth(authtype): def external(func): def wrapper(*args,**kwargs): print("验证方式:%s" % authtype) if authtype=="local": username=input('key in your username:').strip() password=input('key in your password:').strip() if user==username and passwd == password: print('welcome %s'%(username)) res=func(*args,**kwargs) return res else: exit('invalid username or password') elif authtype=="ldap": print('pls install authconfig-gui and setting on it') res = func(*args, **kwargs) return res return wrapper return external def index(): print('welcome to login index') @auth(authtype='local') def home(name): print('welcome to home') print('hello',name) return 'from home' @auth(authtype='ldap') def bbs(): print('welcome to bbs') index() print(home("dj")) bbs() 运行结果: welcome to login index 验证方式:local key in your username:deakin key in your password:123456 welcome deakin welcome to home hello dj from home 验证方式:ldap pls install authconfig-gui and setting on it welcome to bbs