pyextend - python extend lib accepts(exception=TypeError, **types) 參數: exception: 檢查失敗時的拋出異常類型 **types: 待檢查的k-v參數 **types參數支持 a=int : 待測函數參數a必須為 int 類
accepts(exception=TypeError, **types)
參數:
exception: 檢查失敗時的拋出異常類型
**types: 待檢查的k-v參數
**types參數支持
a=int : 待測函數參數a必須為 int 類型, 否則檢查失敗
b='__iter__' : 待測參數 b 必須為 實現 __iter__ 函數的 iterable類型
c=('__iter__', None) : 待測參數 c 必須為實現 __iter__函數的 iterable類型或者None.
範例:
Example 1: @accepts(a=int, b='__iter__', c=str) def test(a, b=None, c=None): print('accepts OK') test(13, b=[], c='abc') -- OK test('aaa', b=(), c='abc') --Failed Example 2: @accepts(a=int, b=('__iter__', None), c=str) def test(a, b=None, c=None): print('accepts OK') test(13, b=[], c='abc') -- OK test(13, b=None, c='abc') -- OK
代碼:
def accepts(exception=TypeError, **types): """ A wrapper of function for checking function parameters type """ def check_param(v, type_or_funcname): if isinstance(type_or_funcname, tuple): results1 = [check_param(v, t) for t in type_or_funcname if t is not None] results2 = [v == t for t in type_or_funcname if t is None] return any(results1) or any(results2) is_type_instance, is_func_like = False, False try: is_type_instance = isinstance(v, type_or_funcname) except TypeError: pass if isinstance(type_or_funcname, str): is_func_like = hasattr(v, type_or_funcname) return is_type_instance or is_func_like def check_accepts(f): assert len(types) <= f.__code__.co_argcount,\ 'accept number of arguments not equal with function number of arguments in "{}"'.format(f.__name__) @functools.wraps(f) def new_f(*args, **kwargs): for i, v in enumerate(args): if f.__code__.co_varnames[i] in types and \ not check_param(v, types[f.__code__.co_varnames[i]]): raise exception("function '%s' arg '%s'=%r does not match %s" % (f.__name__, f.__code__.co_varnames[i], v, types[f.__code__.co_varnames[i]])) del types[f.__code__.co_varnames[i]] for k, v in kwargs.items(): if k in types and \ not check_param(v, types[k]): raise exception("function '%s' arg '%s'=%r does not match %s" % (f.__name__, k, v, types[k])) return f(*args, **kwargs) return new_f return check_accepts