装饰器
定义:本质是函数,为其他函数添加附加的功能。
原则:1、不能修改原函数的源代码
2、不能修改被原函数的调用方式
重点理解:
1、函数即“变量”
2、高阶函数:返回值中包含函数名
3、嵌套函数
高阶函数 + 嵌套函数 = 装饰器
热身: 先感受一下Python的解释器,结果可能和你预想的不同
__author__ = 'jcx' def foo():
print("in the foo")
bar() #解释器依次解释,先声明print后bar def bar():
print("in the bar") #找到bar,定义 foo() #只要在调用前声明就可以
Output:
in the foo
in the bar
应用:
1、通用版 打印程序执行时间
__author__ = 'jcx' import time def timer(func): #timer(test1) func = test1
def deco(*args, **kwargs): #这样写,就可以使被装饰的函数可以带参数
start_time = time.time()
func(*args, **kwargs)
stop_time = time.time()
print("Func RunTime = %s" % (stop_time - start_time))
return deco @timer #等于作了这部赋值 test1 = timer(test1)
def test1():
time.sleep(0.1)
print("in the test1") @timer
def test2(name,age): #test2 = timer(test2) test2() = deco()
print("test2:", name,age) test1() #实际是在执行deco()
test2("jcx",24) #带参数
24
输出结果:
in the test1
Func RunTime = 0.10228705406188965
test2: jcx 24
Func RunTime = 2.09808349609375e-05
2、多种方式登录网页/语法糖/嵌套
__author__ = 'jcx' import time
user,passwd = 'jcx', 'jcx123' def auth(auth_type):
print("auth type: ", auth_type)
def outer_wrapper(func):
def wrapper(*args, **kwargs):
# print("wrapper func: ", *args,**kwargs)
if auth_type == "local":
username = input("Username:".strip())
password = input("Password:".strip())
if user == username and passwd == password:
print("\033[32;1mUser has passed authentication\033[0m")
res = func(*args, **kwargs) #from home
print('-------->after authentication ')
return res
else:
exit("wrong username or password.")
elif auth_type == "ldap":
print('waiting...')
return wrapper
return outer_wrapper @auth
def index():
print("Welcome to index page") @auth(auth_type = "local") # home = auth() wrapper() 通过本地方式登录
def home():
print("Welcome to home page")
return "from home page" @auth(auth_type = "ldap") #通过ldap方式登录
def bbs():
print("Welcome to bbs page") index("local")
home()
输出结果:
auth type: <function index at 0x10ae390e0>
auth type: local
auth type: ldap
Username:jcx
Password:jcx123
User has passed authentication
Welcome to home page
-------->after authentication
waiting...