Python学习笔记 Day 4
装饰器
本质是函数,用来装饰其他函数,就是为其他函数添加附加功能。
原则:
- 不能去修改被装饰的原代码
- 被装饰的函数的调用方式不能动
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 test1():
time.sleep(3)
print('in the test1')
test1()
运行如图:
in the test1
the func run time is 3.0006024837493896
故:实现装饰器知识储备
- 函数即“变量”
- 高阶函数
高阶函数条件(2者有1个即可 ):
(1) 把1个函数当作实参传给另一个函数(实现不去修改被装饰的源代码)
(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()#计算bar函数的运行时间
print("the func run time is %s "%(stop_time-start_time))
#不修改被装饰的原代码bar(),为bar添加附加功能(计时) test1即装饰器
print(bar)#bar函数门号,内存地址,也就是说加括号就是调用
test1(bar)
运行如下:
<function bar at 0x000000FD2E9AB9D8>
in the bar
the func run time is 3.000737428665161
知识2-(2):
import time
def bar():
time.sleep(3)
print('in the bar')
def test2(func):
print(func)
return func#
bar=test2(bar)
#bar内存地址,交给Test2 , 打印又返回bar内存地址,随后稪盖
bar()#运行Bar函数
运行如下:
<function bar at 0x000000FD2E9AB598>
in the bar
装饰器(无参数)
import time
def timer(func):
def deco():
start_time=time.time()
func()#此地址是第一次给的bar1的内存,执行的是bar1()
stop_time=time.time()
print('the func run time is %s' %(stop_time-start_time))
return deco
def bar1():
time.sleep(3)
print('in the bar')
@timer
#此句与bar1=timer(bar1)等同,想谁加上装饰器在哪加@+装饰器名
#只是这里是在bar2前,所有的bar1会成bar2
def bar2():
time.sleep(3)
print('in the bar2')
bar1=timer(bar1)
#把bar1的内存地址交给Timer,Deco函数就是“变量”,
#其接受Timer参数,故其地址就成了bar1的内存地址,并其返回赋值到了新bar1
bar1()#如此一来Bar1成了指向deco,加括号成了运行Deco()
bar2()
运行如下:
in the bar
the func run time is 3.0003163814544678
in the bar2
the func run time is 3.0003561973571777
装饰器(有参数)
import time
def timer(func):#A:func=bar2
def deco(*args,**kwargs):
start_time=time.time()
func(*args,**kwargs)#B:func=bar2
stop_time=time.time()
print('the func run time is %s' %(stop_time-start_time))
return deco
def bar1():
time.sleep(3)
print('in the bar')
@timer
#bar2=timer(bar2),A,故:bar2()=deco(),当bar2()有参数,就可放到B处
#因不知道bar2有多少参数,故;用的是*args,**kwargs,用以接收不知数的参数
def bar2(name,age,sex):
time.sleep(3)
print('in the bar2:',name,age,sex)
bar1=timer(bar1)
bar1()
bar2("liang",18,"male")
运行如下:
in the bar
the func run time is 3.000230073928833
in the bar2: liang 18 male
the func run time is 3.000300645828247
装饰器(高级:装饰器带有参数)
网页登陆认证
Print(home()):打印home函数执行完所返回(return)的值
已往的【func(*args,**kwargs)#B:func=bar2】在源函数要求要有Return内容时,装饰器的【func(*args,**kwargs)#B:func=bar2】不加处理会导致源函数代码的Return内容丢失
故有下方:
res = func(*args, **kwargs) # from home
print("—after authenticaion ")
return res
登陆认证设本地和服务器认证。装饰器要改变升级–装饰器加上了参数
装饰器外嵌多一层函数
- 引用装饰器语句的参数会传到第一层
- 其他与上面两种大同小异
- 断点运行视频 提取码: ydqs
__author__ = "Alex Li"
import time
user,passwd = 'alex','abc123'
def auth(auth_type):
print("auth func:",auth_type)
def outer_wrapper(func):
def wrapper(*args, **kwargs):
print("wrapper func args:", *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,