Decorator裝飾器使用
Decorator
裝飾器能讓你在被裝飾的函式之前與之後執行裝飾器的程式, 延伸函式的呼叫行為, 將共用的功能獨立出來, 不用修改函式
, 加上去即可使用 ,不限制一個數量, 內建裝飾器如@property, @staticmethod各有不同功能:
使用場合:
計算時間decorator(python3.5+)裝飾器能讓你在被裝飾的函式之前與之後執行裝飾器的程式, 延伸函式的呼叫行為, 將共用的功能獨立出來, 不用修改函式
, 加上去即可使用 ,不限制一個數量, 內建裝飾器如@property, @staticmethod各有不同功能:
使用場合:
- 紀錄log
- 管控權限與身份認證
- 在呼叫API時很適合搭配使用
- 在沒明確定義參數數量時使用 *args : 回傳tuple, **kwargs : 回傳Dictionary
import functools
def upercase(func):
functools.wraps(func)
def wrapper(*args, **kwargs):
print args
print kwargs
return func().upper()
return wrapper
@uppercase
def hi('boy',name='Charles'):
return 'Hello'
>>> hi()
('boy')
{name : 'Charles'}
'HELLO'
這裡還有一些方法可以參考
例如快取,debug......
import functools
def cache(func):
memo = {}
@wraps(func)
def _wrapper(*args):
res = memo.get(args, None)
if res is not None:
return res
else:
res = func(*args)
memo[args] = res
return res
return _wrapper
@cache
def fib(n):
if n <= 1:
return n
else:
return fib(n-1) + fib(n-2)
print([fib(i) for i in list(range(31))])
def debug(fn):
def wrapper(*args, **kwargs):
print(fn.__name__, 'called!')
print(sorted(args), tuple(sorted(kwargs.items())))
res = fn(*args, **kwargs)
print(res)
return res
return wrapper
class cache(object):
def __init__(self, fn):
self.fn = fn
self._cache = {}
functools.update_wrapper(self, fn)
def __call__(self, *args, **kwargs):
key = str(args) + str(kwargs)
if key in self._cache:
ret = self._cache[key]
else:
ret = self._cache[key] = self.fn(*args, **kwargs)
return ret
def clear_cache(self):
self._cache = {}
# from http://stackoverflow.com/questions/3627793/best-output-type-and-encoding-practices-for-repr-functions
def stdout_encode(u, default='UTF8'):
encoding = sys.stdout.encoding or default
if sys.version_info > (3, 0):
return u.encode(encoding).decode(encoding)
return u.encode(encoding)
def timeit_wrapper(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter() # Alternatively, you can use time.process_time()
func_return_val = func(*args, **kwargs)
end = time.perf_counter()
print('{0:<10 -="" :="" end="" format="" func.__module__="" func.__name__="" func_return_val="" pre="" return="" start="" wrapper="">10>

沒有留言:
張貼留言