本节内容
1. 装饰器
1.装饰器:本质是函数,(功能:装饰其他函数);就是为其他函数添加功能
原则1:不能修改被装饰的函数的源代码,
2:不能修改被装饰函数的调用方式;
eg.1 decorator1.py
import time
def timmer(func): #定义装饰器:本质就是函数
def warpper(*args,**kwargs):
start_time=time.time()
func()
stop_time=time.time()
print("the func run time is %s" %(stop_time-start_time))
return warpper
@timmer #在定义需要修饰的函数体前,用@装饰器实现调用。
def t1():
time.sleep(3)
print("in the test1!")
t1()
'''装饰器:
1.不修改原函数代码;
2.不修改原函数调用方式。
'''
结果:
in the test1!
the func run time is 3.00007963180542
实现装饰器知识储备:
1.1 函数即“变量”
内存回收机制,当内存中存的数据没有“门牌号”调用时,即回收该内存数据。
结论:函数就是变量,定义一个函数体就是,把函数体赋值给了函数名,跟变量一样有内存回收机制。
eg。
def bar():
print('in the bar')
def t1(func):
print(func)
func() #可以直接运行函数
t1(bar) #打印bar函数的的内存地址
print("---------")
func=bar #将bar函数体的门牌号加一个func,
func() #可以直接运行bar()函数
结果:
<function bar at 0x002FC660>
in the bar
---------
in the bar
1.2 高阶函数
a:把一个函数名,当做实参,传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能);
eg.
import time
def bar():
time.sleep(3)
print('in the bar')
def t1(func):
start_time=time.time()
func() #运行bar函数
stop_time=time.time()
print('the func run time is %s' %(start_time-stop_time))
t1(bar) #打印bar函数运行的时间===========把一个函数名当实参的方式
结果:
in the bar
the func run time is -3.000004291534424
特点:增加了函数的功能了,不过也改变了函数的调用方式。
b:返回值中,包含函数名(不修改函数的调用方式)。
import time
def bar():
time.sleep(3)
print('in the bar')
def t2(func):
print(func)
return func #返回值中返回(调用)函数
bar=t2(bar) #覆盖了之前的bar, bar函数的调用方式也不用变
bar() #bar函数
结果:
<function bar at 0x00D5C660> #bar函数的内存地址
in the bar #三秒后,打印这一行。
1.3 嵌套函数
eg。
def foo(): #函数的嵌套:在一个函数体内,用def去声明另一个函数
print('in the foo')
def bar(): #bar函数的作用域只在foo()函数体内
print("in the bar")
bar() #也只能在foo()中调用。
foo()
# def t1(): #函数的调用
# foo() #函数的调用
# t1()
结果:
in the foo
in the bar
高阶函数+嵌套函数 =》装饰器
import time
def timer(func):
def deco(*args,**kwargs): #带参数的用这个
start_time=time.time()
func(*args,**kwargs) #带参数
stop_time=time.time()
print("the func run time is %s"%(stop_time-start_time))
return deco
@timer #相当于 t1=timer(t1) 放到 被装饰的函数定义前一行
def t1():
time.sleep(1)
print('in the t1')
t1()
@timer #t2=timer(t2)
def t2(name): #带参数
time.sleep(0.5)
print("test2:",name)
t2("kkk")
结果:
in the t1
the func run time is 1.0004582405090332
test2: kkk
the func run time is 0.500312089920044
==============================迭代器========进阶=======
需求:
1、目前有三个页面:index主页面、home页面和bbs页面;
2、之前内测阶段都可以随意登录,目前进入正式阶段需要在home和bbs页面添加
代码:
user,passwd ='kkk','abc123'
def auth(func):
def wrapper(*args,**kwargs):
username=input("Username:").strip()
password=input("Password").strip()
if username==user and password ==passwd:
print("\033[32;1mUser has passed authentication\33[0m")
return func(*args,**kwargs) #加上这条后将原来的返回值也返回回来了
else:
exit("\033[31;1mInvalid username or password\033[0m")
return wrapper
def index():
print("welcome to index page")
@auth
def home():
print("welcome to home page")
return "from home" #home()的返回结果消失了
@auth
def bbs():
print("welcome to bbs page")
index()
home()
bbs()
==============================迭代器========终极=======
需求:
1、目前有三个页面:index主页面、home页面和bbs页面;
2、之前内测阶段都可以随意登录,目前进入正式阶段需要在home和bbs页面添加认证
3、两种认证方式:本地认证和ldap认证;home采用本地认证;bbs采用ldap认证
代码:
user,passwd ='kkk','abc123' #本地认证的用户名密码
def auth(auth_type): #认证类型
print('auth func:',auth_type)
def outer_warpper(func): #先不加参数进行调试,得出此参数为func
def wrapper(*args, **kwargs):
print("warpper func args:",*args,**kwargs)
if auth_type=="local":
username = input("Username:").strip()
password = input("Password").strip()
if username == user and password == passwd:
print("\033[32;1mUser has passed authentication\33[0m")
return func(*args, **kwargs)
else:
exit("\033[31;1mInvalid username or password\033[0m")
elif auth_type=='ldap':
print("搞毛线ldap,不会。。。。")
return wrapper
return outer_warpper
def index():
print("welcome to index page")
@auth(auth_type="local") #auth()加上括号了,直接执行outer_wrapper()了;相当于 home=wrapper
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=warpper
bbs()