python中的装饰器是干嘛的-python中的装饰器

python的装饰器是用来装饰函数的。这是什么意思呢?假如我们有一个函数,这个函数的功能不能满足我们现有的需求,那么我们可以通过装饰器在这个函数执行前执行后做一些我们需要的操作(如果函数本身功能不满足,那就直接修改方法体了,不需要装饰器帮忙)。

1. 简单装饰器

装饰器的语法糖是使用@符号表示,装饰器本身也是一个函数,只不过参数是函数而已。

def decor_function(func):

def wrapper_function():

print("[%s] %s() called" % (ctime(), func.__name__))

return func()

return wrapper_function

@decor_function

def my_func():

print("Hello world")

...

my_func()

decor_function也就是我们的装饰器函数,它对原有的函数进行包装,返回一个包装过的函数wrapper_function。使用@修饰过的函数my_func,返回的函数实际上是装饰器返回的函数wrapper_function.

[Mon Jul 9 17:07:40 2018] my_func() called

Hello world

2. 修饰含有参数的函数

函数定义可以使用任意的参数,那么装饰器函数如何处理呢?其实很简单,使用*args和**kargs就可以方便的调用了,只需要在装饰器函数的返回的函数中将参数传递给被修饰的函数就可以了。

def decor_function(func):

def wrapper_function(*args, **kargs):

print("[%s] %s() called" % (ctime(), func.__name__))

return func(*args, **kargs)

return wrapper_function

@decor_function

def my_func_with_param(name):

print("Hello", name)

my_func_with_param("Joe")

[Mon Jul 9 17:12:58 2018] my_func_with_param() called

Hello Joe

3. 装饰函数带参数

装饰器函数本身也是可以带参数的,使用参数,可以根据具体的场景添加不同的功能实现。

def decor_function_with_parm(level):

if level == "info":

logging.info("info message logged")

elif level == "error":

logging.error("error message logged")

else:

logging.debug("debug message logged")

def wrapper_outter_func(func):

def wrapper_inner_func(*args, **kargs):

func(*args, **kargs)

return wrapper_inner_func

return wrapper_outter_func

@decor_function_with_parm(level="info")

def my_func2(name):

print("Hello,", name)

my_func2("Joe")

带参数的装饰器函数写起来比较麻烦,因为需要处理的参数比较多,一般最外层的函数处理装饰器参数,接下来的函数处理func,最后一层函数用来处理被修饰的函数的参数。

4. 多重修饰

一个函数可以被多个装饰器修饰,like this

@decor_function_with_parm(level="info")

@decor_function

def my_func():

print("Hello world")

执行的顺序是:

f = decor_function_with_parm(level='info', decor_function(my_func()))

5.使用类来处理

类的__call__()方法可以把类当成函数来处理,所以类也可以用做装饰器

class Decor:

def __init__(self, func):

print("__init__ method called")

self.func = func

def __call__(self, *args, **kargs):

print("__call__ method called")

self.func(*args, **kargs)

@Decor

def func(name):

print("func called")

print("Hello,",name)

func("joe")

使用类做装饰器时,init函数中添加被修饰函数的引用,在call函数中处理参数。

__init__ method called

__call__ method called

func called

Hello, joe

6.保留函数的元信息

被修饰之后的函数,它的元信息都消失,被替换的wrapper函数代替。python中提供了functools.wraps来保存函数的元信息。wraps本身也是个装饰器

def decor_function(func):

@wraps(func)

def wrapper_function(*args, **kargs):

print("[%s] %s() called" % (ctime(), func.__name__))

print(func.__name__)

return func(*args, **kargs)

return wrapper_function

@decor_function

def my_func_with_param(name):

print("Hello", name)

my_func_with_param('joe')

print(my_func_with_param.__name__)

[Mon Jul 9 18:16:11 2018] my_func_with_param() called

my_func_with_param

Hello joe

my_func_with_param

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值