python装饰器
与Java 中Spring Aop很相似
与 Tomcat 的 Filter 也很像
函数是一等公民
def func(message):
print("Hello ,{}".format(message))
hello = func
hello('world')
Hello ,world
函数当参数
def func(message):
print("Hello ,{}".format(message))
def caller(func,message):
func(message)
caller(func," python ")
Hello , python
函数的嵌套
def func(message):
def hello(message):
print("hello , {}!".format(message))
return hello(message)
func("world")
hello , world!
手工装饰
def func():
print("Hello World")
def decorator(func):
def wrapper():
print("Before")
func()
print("After")
return wrapper
func = decorator(func)
func()
Before
Hello World
After
注解装饰器
def decorator(func):
def wrapper():
print("Before decorator")
func()
print("After decorator")
return wrapper
@decorator
def func():
print("Hello World")
func()
Before decorator
Hello World
After decorator
带参数的装饰器
def decorator(func):
def wrapper(message):
print("Before decorator")
func(message)
print("After decorator")
return wrapper
@decorator
def func(message):
print("Hello {}!!".format(message))
func("world")
Before decorator
Hello world!!
After decorator
@decorator
def func(message,fromWho):
print("Hello {}!! from {}".format(message,fromWho))
def decorator(func):
def wrapper(message,fromWho):
print("Before decorator")
func(message,fromWho)
print("After decorator")
return wrapper
func("world","python")
Before decorator
Hello world!! from python
After decorator
可用于任何参数形式的函数装饰器
import functools
def decorator_super(func):
@functools.wraps(func)
def wrapper(*args,**kwargs):
print("Before decorator")
func(*args,**kwargs)
print("After decorator")
return wrapper
@decorator_super
def func1(message,fromWho):
print("Hello {}!! from {}".format(message,fromWho))
@decorator_super
def func2(message):
print("Hello {}!!".format(message))
func1("world","python")
print("---------")
func2("world")
print("---------")
print(func1.__name__)
print(func2.__name__)
Before decorator
Hello world!! from python
After decorator
---------
Before decorator
Hello world!!
After decorator
---------
func1
func2
Class 类装饰器
class Count:
def __init__(self,func):
self.func = func
self.nums_called = 0
def __call__(self,*args,**kwargs):
self.nums_called += 1
print("Called {} times".format(self.nums_called))
return self.func(*args,**kwargs)
@Count
def func():
print("Hello World")
func()
func()
func()
Called 1 times
Hello World
Called 2 times
Hello World
Called 3 times
Hello World
装饰器的叠加嵌套
@Count
@decorator_super
def func():
print("Hello World")
func()
func()
func()
Called 1 times
Before decorator
Hello World
After decorator
Called 2 times
Before decorator
Hello World
After decorator
Called 3 times
Before decorator
Hello World
After decorator
来整活了。1-认证、2-日志、3-检查、4-计时
import functools
def authenticate(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
request = args[0]
if check_user_logged_in(request): # 如果用户处于登录状态
return func(*args, **kwargs) # 执行函数post_comment()
else:
raise Exception('Authentication failed')
return wrapper
@authenticate
def post_comment(request):
print("do comment")
def check_user_logged_in(request):
#return False
return True
post_comment("request")
do comment
import time
import functools
def log_execution_time(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
res = func(*args, **kwargs)
end = time.perf_counter()
print('{} took {} ms'.format(func.__name__, (end - start) * 1000))
return res
return wrapper
@log_execution_time
def calculate_similarity(items):
sum = 0
for i in range(items):
sum += i
return sum
calculate_similarity(100000)
calculate_similarity took 10.108035000030213 ms
4999950000
import functools
def checkInput(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
id = args[0]
if(id == "valid"):
return func(*args, **kwargs) # 执行函数post_comment()
else:
raise Exception('Input format error')
return wrapper
@checkInput
def post_comment(flag,request):
print("do comment")
post_comment("valid","json data")
#post_comment("invalid","json data")
do comment