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>
沒有留言:
張貼留言