前端 python decrorator

chao87 · August 21, 2019 · 60 hits

用了 python 好久, 惭愧的是一些高级的语法糖就没怎么用过。花了点时间好好研究一下 python 装饰器。
所谓装饰, 就是想要对一些已经有的模块做一些修饰工作, 但又不让这个功能侵入到原有代码中去,常用的使用场景例如, 插入日志, 性能测试, 事务处理等等, 有了装饰器, 就可以提取大量函数中与本身功能无关的代码,从而重用代码。

1
2
3
4
5
6
7
8
9
10
11
import datetime

def (func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper

@log
def now():
print(datetime.datetime.today())

对上面代码的注解:

  1. 函数 log 中需要一个 func 的参数, 也就是用来回调的函数。
  2. 在 now 函数前有一个@log, 即之前我们定义的函数

当我们调用 now 函数时, now() 返回了 wrapper() 函数, 所以 now 其实变成了 wrapper 的一个变量, 而后面的 log 执行其实变成了 wrapper()

1
2
3
now()
call now():
2015-06-18 11:00:52.339373

这样, 装饰器没有影响到原来的函数,也没影响函数调用的模块。

而多个装饰器,

1
2
3
4
@decorator1
@decorator2
def now():
print(datetime.datetime.today())

其实等价于 now = decorator1(decorator2(now))
(其实就是说装饰器的调用顺序与其声明的顺序相反)

而如果装饰器自己带参数, 其实就是说装饰器这个函数需要返回一个真正的 decorator
比如:(本例子引用自廖雪峰 python3 装饰器)

1
2
3
4
5
6
7
def log(text):
def decorator(func):
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator

若调用

1
2
3
@log
def now():
print(datetime.datetime.today())

实际上就是
now = decorator(text)(now)

而如果被装饰的那个函数带参数, 则装饰器的函数也需要加入对应参数

1
2
3
4
5
6
7
8
9
10
def log(func):
def wrapper(text2):
print('%s' % (func.__name__))
return func(text2)
return wrapper

@log
def now(text2):
print(datetime.datetime.today())
print(text2)

比如调用

1
now("haha")

输出如下:

1
2
3
now
2015-06-18 11:20:11.246544
haha

简单的总结到这里, 比较好的例子可以参看
Python 修饰器的函数式编程

No Reply at the moment.
You need to Sign in before reply, if you don't have an account, please Sign up first.