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("33[32;1mUser has passed authenticatiom33[0m")
return func(*args,**kwargs)
else:
exit("33[31;1mInvalid username or password33[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("33[32;1mUser has passed authenticatiom33[0m")
return func(*args,**kwargs)
else:
exit("33[31;1mInvalid username or password33[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()

运行结果:



原文地址:https://www.cnblogs.com/rainowl-ymj/p/7094368.html