How to use Python decorators to check function arguments?

后端 未结 8 1672
情歌与酒
情歌与酒 2020-11-28 22:56

I would like to define some generic decorators to check arguments before calling some functions.

Something like:

@checkArguments(types = [\'int\', \'         


        
8条回答
  •  天命终不由人
    2020-11-28 23:25

    To enforce string arguments to a parser that would throw cryptic errors when provided with non-string input, I wrote the following, which tries to avoid allocation and function calls:

    from functools import wraps
    
    def argtype(**decls):
        """Decorator to check argument types.
    
        Usage:
    
        @argtype(name=str, text=str)
        def parse_rule(name, text): ...
        """
    
        def decorator(func):
            code = func.func_code
            fname = func.func_name
            names = code.co_varnames[:code.co_argcount]
    
            @wraps(func)
            def decorated(*args,**kwargs):
                for argname, argtype in decls.iteritems():
                    try:
                        argval = args[names.index(argname)]
                    except ValueError:
                        argval = kwargs.get(argname)
                    if argval is None:
                        raise TypeError("%s(...): arg '%s' is null"
                                        % (fname, argname))
                    if not isinstance(argval, argtype):
                        raise TypeError("%s(...): arg '%s': type is %s, must be %s"
                                        % (fname, argname, type(argval), argtype))
                return func(*args,**kwargs)
            return decorated
    
        return decorator
    

提交回复
热议问题