Python 3.x--装饰器
————————装饰器=高阶函数+嵌套函数(闭包)——————————
高阶函数:1、把一个函数名当做实参传递给另一个函数;2、返回值中包含函数名
def func1():
print("this is func1")
def test(func):
print(func)
func()
test(func1)
输出结果:
闭包
关于闭包主要有下面两种说法:
- 闭包是符合一定条件的函数,定义为:闭包是在其词法上下文中引用了自由变量的函数
- 闭包是由函数与其相关的引用环境组合而成的实体。定义为:在实现绑定时,需要创建一个能显示表示引用环境的东西,并将它与相关的子程序捆绑在一起,这样捆绑起来的整体称为闭包
我们对函数的定义是:一些可执行的代码,这些代码在函数定义后就确定了,不会在执行时发生变化,所以一个函数只有一个实例。
闭包在运行的时候可以有多个实例,不同的引用环境和相同的环境组合可以产生不同的实例。
这里有一个词:引用环境,其实引用环境就是在执行运行的某个时间点,所有处于活跃状态的变量所组成的集合,这里的变量是指变量的名字和其所代表的对象之间的联系。
可以使用闭包语言的特点:
- 函数可以作为另外一个函数的返回值或者参数,还可以作为一个变量的值。
- 函数可以嵌套使用
装饰器:为其他函数添加附加功能,不改变原函数代码及调用方式
import time
def bar():
time.sleep(2)
print("this is bar")
def test1(func1):
print(func1)
return func1
bar = test1(bar)
bar()
不改变调用方式,未添加新功能---------
import time
def deco(func):
start_time = time.time()
return func
stop_time = time.time()
print('Running time is %s:'%(stop_time-start_time))
def test1():
time.sleep(2)
print("this is test1")
def test2():
time.sleep(2)
print("this is test2")
test1 = deco(test1)
test1()
test2 = deco(test2)
test2()
运行结果:
不改变调用方式,添加新功能---------
import time
def timer(func):
def deco():
start_time = time.time()
func()
stop_time = time.time()
print('Running time is %s:'%(stop_time-start_time))
return deco
def test1():
time.sleep(2)
print("this is test1")
def test2():
time.sleep(3)
print("this is test2")
test1 = timer(test1)
test1()
test2 = timer(test2)
test2()
运行结果:
使用@符号-----------
import time
def timer(func):
def deco():
start_time = time.time()
func()
stop_time = time.time()
print('Running time is %s:'%(stop_time-start_time))
return deco
@timer
def test1():
time.sleep(2)
print("this is test1")
def test2():
time.sleep(3)
print("this is test2")
test1()
test2 = timer(test2)
test2()
原函数带有参数-----------
import time
def timer(func):
def deco(*arg,**kwarg):
start_time = time.time()
func(*arg,**kwarg)
stop_time = time.time()
print('Running time is %s:'%(stop_time-start_time))
return deco
@timer
def test1():
time.sleep(2)
print("this is test1")
@timer #test2 = timer(test2)
def test2(name,age):
time.sleep(1)
print("this is test2:",name,age)
test1()
test2('lili',18)
运行结果:
原函数有返回值----------
user,passwd = 'lili','abc'
def auth(func):
def wrapper(*args,**kwargs):
username = input("Username:").strip()
password = input("Passwd:").strip()
if user == username and passwd ==password:
print("\033[32;1mUser has passed authenticatiom\033[0m")
return func(*args,**kwargs)
else:
exit("\033[31;1mInvalid username or password\033[0m")
return wrapper
@auth
def page1():
print("this is page1")
return "from page1"
@auth
def page2():
print("this is page2")
@auth
def page3():
print("this is page3")
print(page1())
运行结果:
装饰器带参数-------------
user,passwd = 'lili','abc'
def auth(auth_type):
print("auth_arge:",auth_type)
def outer_wrapper(func):
def wrapper(*args,**kwargs):
if auth_type == 'p1':
username = input("Username:").strip()
password = input("Passwd:").strip()
if user == username and passwd ==password:
print("\033[32;1mUser has passed authenticatiom\033[0m")
return func(*args,**kwargs)
else:
exit("\033[31;1mInvalid username or password\033[0m")
elif auth_type == 'p2':
print('p2 pass')
return wrapper
return outer_wrapper
@auth(auth_type = "p1")
def page1():
print("this is page1")
return "from page1"
@auth(auth_type = "p2")
def page2():
print("this is page2")
print(page1())
page2()
运行结果: