装饰器就是对已有函数添加功能,又可以不去修改原有的函数的方法。它的实现依赖于高阶函数(HOF)。这里主要参考着两篇文章来学习
In [6]:
# 不带参数的简单装饰器
def use_logging(func):
def wrapper(*args, **kwargs):
print("Hello,", func.__name__)
func(*args, **kwargs)
return wrapper
@use_logging
def foo():
print("I am Longshan DU")
foo()
In [10]:
# 带参数的装饰器
def use_logging(level):
def decorator(func):
def wrapper(*args, **kwargs):
if level == 'warn':
print("The log level of %s is 'warn'" %func.__name__)
elif level == 'info':
print("The log level of %s is 'info'" %func.__name__)
return func(*args, **kwargs)
return wrapper
return decorator
@use_logging(level='warn')
def foo():
print("I am Longshan DU")
foo()
In [13]:
# 类装饰器
class Foo(object):
def __init__(self, func):
self._func = func
def __call__(self, *args, **kwargs):
print('Class decorator running')
self._func(*args, **kwargs)
print('Class decorator ending')
@Foo
def bar(name):
print('I am', name)
bar('Longshan')
In [22]:
# functools.wraps
import functools
def use_logging(level):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
if level == 'warn':
print("The log level of %s is 'warn'" %func.__name__)
elif level == 'info':
print("The log level of %s is 'info'" %func.__name__)
return func(*args, **kwargs)
return wrapper
return decorator
@use_logging(level='warn')
def foo():
print("I am Longshan DU")
foo()
print(foo.__name__)
In [31]:
# 类装饰器
import functools
class Foo(object):
def __init__(self, func):
self._func = func
functools.wraps(self._func)
def __call__(self, *args, **kwargs):
print('Class decorator running')
self._func(*args, **kwargs)
print('Class decorator ending')
@Foo
def bar(name):
print('I am', name)
bar('Longshan')
print(bar.__class__.__name__)
In [51]:
# 通过*args修改decoratee的参数
def decorate_A(func):
def wrapper(*args, **kwargs):
hello = 'Hello'
args = (hello,) + args
return func(*args, **kwargs)
return wrapper
@decorate_A
def print_message_A(*name):
print(*name)
print_message_A('Longshan')
# 通过\*\*kwargs修改的decoratee的参数
def decorate_B(func):
def wrapper(*args, **kwargs):
kwargs['hello'] = 'Hello'
return func(*args, **kwargs)
return wrapper
@decorate_B
def print_message_B(*args, **kwargs):
print(kwargs['hello'], *args)
print_message_B('Longshan DU')
# 约定好参数,直接修改
def decorate_C(func):
def wrapper(*args, **kwargs):
hello = 'Hello, world!'
return func(hello)
return wrapper
@decorate_C
def print_message_C(hello):
print(hello)
print_message_C('Longshan')
In [1]:
# 给函数做缓存
from functools import wraps
def memo(func):
cache = {}
miss = object()
def wrapper(*args, **kwargs):
result = cache.get(func, miss)
if result is miss:
result = func(*args, **kwargs)
cache[args] = result
return result
return wrapper
@memo
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
print(fib(30))
In [8]:
# 注册回调函数
class MyApp():
def __init__(self):
self.func_map = {}
def register(self, name):
def wrapper(func):
self.func_map[name] = func
return func
return wrapper
def call_method(self, name=None):
func = self.func_map.get(name, None)
if func is None:
raise Exception("No functin registered against - " + str(name))
return func()
app = MyApp()
@app.register('/')
def main_page_func():
return 'This is the main page.'
@app.register('/next_page')
def next_page_func():
return 'This is the next page.'
print(app.call_method('/'))
print(app.call_method('/next_page'))
In [ ]: