Decorator to print function call details - parameters names and effective values

前端 未结 5 607
失恋的感觉
失恋的感觉 2020-12-05 05:46

I want to make a function that being a decorator to another function will print that function call details - parameters names and effective values. My current implementation

5条回答
  •  暖寄归人
    2020-12-05 06:10

    Here is the updated version for Python 3.6+

    import inspect
    
    
    def dump_args(func):
        """
        Decorator to print function call details.
    
        This includes parameters names and effective values.
        """
    
        def wrapper(*args, **kwargs):
            func_args = inspect.signature(func).bind(*args, **kwargs).arguments
            func_args_str = ", ".join(
                "{} = {!r}".format(*item) for item in func_args.items()
            )
            print(f"{func.__module__}.{func.__qualname__} ( {func_args_str} )")
            return func(*args, **kwargs)
    
        return wrapper
    
    
    @dump_args
    def test(a, b=4, c="blah-blah", *args, **kwargs):
        pass
    
    
    test(1)
    test(1, 3)
    test(1, d=5)
    test(1, 2, 3, 4, 5, d=6, g=12.9)
    

    Old version


    Working version with default values:

    def dumpArgs(func):
        '''Decorator to print function call details - parameters names and effective values'''
        def wrapper(*func_args, **func_kwargs):
            arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
            args = func_args[:len(arg_names)]
            defaults = func.func_defaults or ()
            args = args + defaults[len(defaults) - (func.func_code.co_argcount - len(args)):]
            params = zip(arg_names, args)
            args = func_args[len(arg_names):]
            if args: params.append(('args', args))
            if func_kwargs: params.append(('kwargs', func_kwargs))
            print func.func_name + ' (' + ', '.join('%s = %r' % p for p in params) + ' )'
            return func(*func_args, **func_kwargs)
        return wrapper  
    
    @dumpArgs
    def test(a, b = 4, c = 'blah-blah', *args, **kwargs):
        pass
    
    test(1)
    test(1, 3)
    test(1, d = 5)
    test(1, 2, 3, 4, 5, d = 6, g = 12.9)
    

    Result:

    >>> test  (  a = 1, b = 4, c = 'blah-blah' )
    test  (  a = 1, b = 3, c = 'blah-blah' )
    test  (  a = 1, b = 4, c = 'blah-blah', kwargs = {'d': 5} )
    test  (  a = 1, b = 2, c = 3, args = (4, 5), kwargs = {'d': 6, 'g': 12.9} )
    

提交回复
热议问题