python学习-装饰器

概述

学习一下python的装饰器函数。关于装饰器的定义,底层,肯定说得不如网上的文章好。这里就简单记录一下其使用。

需求

python的装饰器其实是一种面向切面的编程方式,可以将大量可复用的代码抽离出来进行复用,这样的编程方式显得优雅。其主要需求有几种:

  1. 插入日志
  2. 性能测试
  3. 权限检验
  4. 事务处理
  5. 缓存

语法

装饰器的语法也很简单,其原理可以先这样理解:
假设我们要为一个函数打印log

1
2
3
4
5
6
7
8
9
def foo():
print("I am foo")

def print_log_for_foo(func):
print("Hello log")
func()


print_log_for_foo(foo)

这样我们就为foo打印了log,但不是很优雅,因为我们调用的是另一个函数,这样显得杂乱无章。用了装饰器就显得清晰明白了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def decoration(func):
def wrapper(*args,**kw):
print("Hello logs")
return func(*args,**kw)
return wrapper

@decoration
def foo():
print('Hello I am foo')

foo() # 调用foo


>>> 输出
Hello logs
Hello I am foo

同样的,这样还存在一些问题,[foo函数]被[wrapper函数]包裹住了,这个时候,函数的元信息就变成了[wrapper函数]的了.

1
print(foo.__name__) # wrapper

这个时候我们要引入另一个装饰函数,把元信息也给传进去.
所以废话这么多,完整的case是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from functools import wraps
def decoration(func):
@wraps(func)
def wrapper(*args,**kw):
print("Hello logs")
return func(*args,**kw)
return wrapper

@decoration
def foo():
print('Hello I am foo')

a = foo() # 调用foo
print(foo.__name__) # foo

>>> 输出
Hello logs
Hello I am foo
foo

类装饰器

类也有装饰器,其装饰器是通过

函数```来实现的.通过@调用了这个函数
1
2


class Decorations(object):
def init(self,func):
self.func = func

def __call__(self):
    print('Hello i am decarations')
    self.func()

@Decorations
def foo():
print(‘i am foo’)

foo()

1
2
3
4
5
6
7
8
9

类装饰器具有以下优点
1. 灵活度大
2. 高内聚
3. 封装性

# 总结
当然平时一些小东西,也就用函数装饰器就足够使用了。
最后附上写flask时候验证admin权限的装饰器

def adminRequired(func):
@functools.wraps(func)
def decoration(*args,**kw):
if current_user.is_authenticated and current_user.is_admin == 1:
return func(*args,**kw)
else:
return redirect(url_for(‘auth.login’))
return decoration

@admin.route(’/’)
@adminRequired
def home():
return “Hello This is admin”


# 参考
https://foofish.net/python-decorator.html 
https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014318435599930270c0381a3b44db991cd6d858064ac0000