装饰器的一个详解
对比一下熟悉的 Java,我觉得装饰器的作用,和 Java 中的代理类一样。
但本贴中举的例子,应该是类似于 Java 中的静态代理类,高级的动态代理类还没有接触
py2.4之前的装饰器写法
def decorate(func):
def wrapper():
print("decorate {}".format(func.__name__))
return func()
return wrapper
def f():
print("this is f")
f = decorate(f)
f()
在这一个写法中,会发现,装饰器相似于闭包
闭包是什么
使用 @ 的写法
将 “@装饰器的名字” 放在被装饰的函数之上,即可
def decorate(func):
def wrapper():
print("decorate {}".format(func.__name__))
return func()
return wrapper
@decorate
def f():
print("this is f")
f()
使用装饰器如何传参数
Python提供了可变长参数 *args和关键字参数 **kwargs,有了这两个参数,装饰器就可以用于任意目标函数了。
def decorate(func):
def wrapper(*args, **kwargs):
print("decorate {}".format(func.__name__))
return func(*args, **kwargs)
return wrapper
@decorate
def f(str):
print("this is {}".format(str))
f('start')
高级的装饰器:
高级的装饰器应该就是java中的动态代理了,这里还没学到,就不做探究了
问题
def decorate(func):
def wrapper():
print("decorate {}".format(func.__name__))
return func
# print(wrapper()) # <function f at 0x0000000002914400>
# print(wrapper) # <function decorate.<locals>.wrapper at 0x0000000002914488>
return wrapper()
def f():
print("this is f")
print(decorate(f)) # <function f at 0x00000000026E4400>
print(decorate) # <function decorate at 0x00000000026E4378>
在return中写 wrapper() 和 wrapper 的区别是啥?
解答:
wrapper | wrapper() |
---|---|
得到的是函数(函数也是一种类对象),所以在print(wrapper)中,输出的是<function decorate..wrapper at 0x0000000002914488> | 得到的是函数 wrapper 的返回值,所以在print(wrapper())中,输出的是返回的函数 f <function f at 0x0000000002914400> |
如果我只写 wrapper
def decorate(func):
def wrapper():
print("decorate {}".format(func.__name__))
return func
return wrapper
def f():
print("this is f")
f = decorate(f)
f()
结果是
如果写 wrapper()
def decorate(func):
def wrapper():
print("decorate {}".format(func.__name__))
return func
return wrapper()
def f():
print("this is f")
f = decorate(f)
f()