python装饰器解析_【Python】解析Python中的装饰器

python中的函数也是对象,函数可以被当作变量传递。

装饰器在python中功能非常强大,装饰器允许对原有函数行为进行扩展,而不用硬编码的方式,它提供了一种面向切面的访问方式。

装饰器

一个普通的装饰器一般是这样:

importfunctoolsdeflog(func):

@functools.wraps(func)def wrapper(*args, **kwargs):print('call %s():' % func.__name__)print('args = {}'.format(*args))return func(*args, **kwargs)return wrapper

这样就定义了一个打印出方法名及其参数的装饰器。

调用之:

@logdeftest(p):print(test.__name__ + "param:" +p)

test("I'm a param")

输出:

call test():

args = I'm a param

test param: I'm a param

装饰器在使用时,用了@语法,让人有些困扰。其实,装饰器只是个方法,与下面的调用方式没有区别:

deftest(p):print(test.__name__ + "param:" +p)

wrapper=log(test)

wrapper("I'm a param")

@语法只是将函数传入装饰器函数,并无神奇之处。

值得注意的是@functools.wraps(func),这是python提供的装饰器。它能把原函数的元信息拷贝到装饰器里面的 func 函数中。函数的元信息包括docstring、name、参数列表等等。可以尝试去除@functools.wraps(func),你会发现test.__name__的输出变成了wrapper。

带参数的装饰器

装饰器允许传入参数,一个携带了参数的装饰器将有三层函数,如下所示:

importfunctoolsdeflog_with_param(text):defdecorator(func):

@functools.wraps(func)def wrapper(*args, **kwargs):print('call %s():' % func.__name__)print('args = {}'.format(*args))print('log_param = {}'.format(text))return func(*args, **kwargs)returnwrapperreturndecorator

@log_with_param("param")deftest_with_param(p):print(test_with_param.__name__)

看到这个代码是不是又有些疑问,内层的decorator函数的参数func是怎么传进去的?和上面一般的装饰器不大一样啊。

其实道理是一样的,将其@语法去除,恢复函数调用的形式一看就明白了:

#传入装饰器的参数,并接收返回的decorator函数

decorator = log_with_param("param")#传入test_with_param函数

wrapper =decorator(test_with_param)#调用装饰器函数

wrapper("I'm a param")

输出结果与正常使用装饰器相同:

call test_with_param():

args = I'm a param

log_param = param

test_with_param

至此,装饰器这个有点费解的特性也没什么神秘了。

装饰器这一语法体现了Python中函数是第一公民,函数是对象、是变量,可以作为参数、可以是返回值,非常的灵活与强大。

原文链接:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值