您的位置:首页 > 编程语言 > Python开发

Python装饰器(&闭包)

2018-12-17 23:35 267 查看

   Python有一个强大的特性—装饰器,它可以给已经实现的代码块(函数)包裹上自己想要添加的功能,而不用考虑函数内是怎么实现的

阐述装饰器之前可以先了解一下Python另一个特性—闭包

闭包

闭包是在函数内再定义一个函数,并且提供了子函数需要的变量,这样可以把子函数与其用到的变量叫做闭包

[code]def line_para(a, b):
def line(x):
return a * x + b
return line

如上代码,定义一个line_para函数,其返回的是子函数line,line_para内定义函数line,这样实现了一个闭包,可以通过传入不同的参数a, b,来获得不同的数学上的二元一次函数

[code]line1 = line_para(2, 4)
line2 = line_para(3, 6)
print(line1(10))
print(line2(10))
# 24
# 36

闭包可以根据需要,创建不同的,又具有一定相似度的函数。这种思想也是装饰器的思想

装饰器

上文有描述,装饰器可以给以实现的函数添加功能。这是一种优雅的实现方法,符合敏捷开发的封闭开放原则。

封闭开放原则:已经实现的功能代码不允许被修改,而是将其扩展

[code]import time

def my_func(func):
def inner(a)
print(time.time())
func(a)
print(time.time())
return inner

@my_func
def other_func(a):
pass

other_func(123)

如上my_func就是实现一个简单的装饰器,假设函数other_func是从别人那儿拿来的,我们并不知道它是怎么实现的,只知道想要给他添加运行开始时间和结束时间。我们可以这样来理解它:

  1. 符号"@"标识程序会使用一个装饰器my_func,
  2. 程序将函数other_func作为参数传入装饰器my_func,之后又将返回值赋值给变量other_func
    [code]other_func = my_func(other_fun)
  3. 然后将原函数other_function的参数传给装饰器my_function返回的对象
    [code]my_func(other_func)(a)
  4. 这样再执行other_func就相当于执行装饰器my_func返回的对象inner函数,执行inner函数就会先打印一下时间戳,然后执行func函数,此时局部变量func指向的是原函数other_func的函数体,也就是执行原函数other_func,最后再打印一下时间戳,这样就实现了一个给原函数other_func添加显示开始、结束时间功能的装饰器

类装饰器

上面是用函数的方式实现装饰器,其实装饰器还可以通过类来实现

[code]import time

class my_func:
def __init__(self, func):
self._func = func

def __call__(self, *args, **kwargs):
print(time.time())
self._func(*args, **kwargs)
print(time.time())

@my_func
def other_func(a)
pass

other_func(123)

其运行的原理其实和函数实现方法差不多:

  1. 符号"@"标识程序会使用一个装饰器my_function
  2. 将函数other_func传给类my_func的实例,之后又将其返回值赋值给other_function
    [code]other_func = my_func(other_func)
  3. 这样运行other_func就是运行类my_func的实例,参数就会被传入__call__方法中,执行call方法就可以实现打印开始时间戳,执行原函数other_func,打印结束时间戳

装饰器很强大,在Python中很多地方都用到它,比如Flask就是通过其实现了很多功能,有待我以后慢慢描述~~

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: