对python装饰器的理解
其出发点仍然是代码重用。所谓装饰就是在一般事物(函数)的外围加上一些并不属于这个事物核心的东西。因此装饰器所执行的内容并不属于所修饰函数的核心内容。相反,其一般用于提供切面功能,如:插入日志、事务处理、缓存、权限校验等等。因为这类功能可以归纳到一个函数中,装饰器的存在将使得实现切面功能只需添加一两行代码即可。decorator实质上就是一个返回函数的高阶函数。
装饰器使用@符号实现,后面接一个返回函数的函数:
# source from: https://www.liaoxuefeng.com/
def log(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
@log
def printNow():
print(time.strftime("%Y/%m/%d/ %H:%M:%S",time.localtime()))
经过@log修饰的函数,被调用时,相当于执行:
log(printNow)()
@符号的使用
这里我们还可以探讨一下@符号的使用:
- @符号后面接了不返回函数的函数
- 使用@property 修饰函数
@符号后面接了不返回函数的函数
def funcA(A):
print("function A")
print(A)
def funcB(B):
print(B(2))
print("function B")
@funcA
@funcB
def func(c):
print("function C")
return c**2
这段代码的是执行结果是:
function C
4
function B
function A
None
那到底是怎么个执行顺序呢?实际上执行的语句相当于:
funcA(funcB(func))
这里先执行 funcB(func)
,因此首先执行了func(2)
,然后打印了它返回的结果4
,接着打印function B
。然后funcB
执行完毕,但没有返回值,因此此时funcA
的参数 A
为None
,所以继而执行了funcA()
。那为什么这里我们并没有调用func()
,只是定义了func
,而它却被执行了呢?这是我目前仍有疑问的,欢迎大佬们赐教。
使用@property 修饰函数
这个用法倒是很常见,可以将类属性的get
和set
方法写成更优雅的形式
class Shape(Object):
def __init__():
self._name = 'wsmz'
@property
def name():
return self._name
@name.setter
def name(nm): # 注意:这里函数的名字必须和被声明成property的函数的名字一样
self._name = nm
s = Shape()
print(s.name)
s.name = 'whsmz'