Python函数小结(2)-- 装饰器、 lambda

  本篇依然是一篇学习笔记,文章的结构首先讲装饰器,然后讲lambda表达式。装饰器内容较多,先简要介绍了装饰器语法,之后详细介绍理解和使用不带参数装饰器时应当注意到的一些细节,然后实现了一个简单的缓存装饰器作为实践,最后在理解不带参数的装饰器的基础上,介绍了理解和使用带参数的装饰器需要注意到的细节。lambda表达式的讲解依然着重于使用细节和理解上。如果有不对的地方欢迎指正。

装饰器

  实际上理解装饰器的作用很简单,在看core python相关章节的时候大概就是这种感觉。只是在实际应用的时候,发现自己很难靠直觉决定如何使用装饰器,特别是带参数的装饰器,于是摊开来思考了一番,写下一些心得。

装饰器简述

  为了完整起见,这里简要说明一下装饰器的语法。装饰器分为带参数得装饰器以及不带参数得装饰器。装饰器以及使用效果看起来大概是这样的。

#语法是这个样子的
@decorator(dec_opt_args)
def func2Bdecorated(func_opt_args):
    ...
#不带参数的装饰器
@dec1
@dec2
def func():
    ...
#这个函数声明等价于
func = dec1(dec2(func))

#带参数的装饰器
@dec(some_args)
def func():
    ...
#这个函数声明等价于
func = dec(some_args)(func)

不带参数的装饰器需要注意的一些细节

  这里将说明使用带参数的装饰器时需要注意的一些细节。并会实现一个简单缓存装饰器,来帮助理解。

1. 关于装饰器函数(decorator)本身

  对于被装饰的函数func,不带参数的装饰器接受一个函数为参数,并返回一个装饰过的函数decorated_func。因为对返回的函数没有限制,所以decorator函数甚至可以返回与func完全无关的新函数。但是大部分情况下,decorated_func是对func的额外处理,因此一个装饰器一般对应两个函数,一个是decorator函数,用来进行一些初始化操作处理,一个是decorated_func用来实现对被装饰的函数func的额外处理。并且为了保持对func的引用,decorated_func一般作为decorator的内部函数,比如:

#一般将decorated_func作为decorator的内部函数
#因为内部函数可以保持对func的引用(详见(1)的闭包讲解)
>>> def decorator(func):
...     print 'init opration'
...     def decorated_func():
...             return func(2)
...     return decorated_func
... 

2. decorator函数只在函数声明的时候被调用一次


  装饰器实际上是语法糖,在声明函数之后就会被调用,产生decorated_func,并把func符号的引用替换为decorated_func。之后每次调用func函数,实际调用的是decorated_func。

>>> def decorator(func):
...     def decorated_func():
...         func(1)
...     return decorated_func
... 
#声明时就被调用
>>> @decorator
... def func(x):
...     print x
... 
decorator being called  
#使用func()函数实际上使用的是decorated_func函数
>>> func()
1
>>> func.__name__
'decorated_func'

  如果要保证返回的decorated_func的函数名与func的函数名相同,应当在decorator函数返回decorated_func之前,加入decorated_func.name = func.name, 另外functools模块提供了wraps装饰器,可以完成这一动作。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值