如何打印args和kwargs列表

3

在我的代码中,有很多地方我会将一个函数及其参数传递给另一个函数。为了调试目的,我想要打印出函数的名称和参数列表。例如:

def process(f, *args, **kwargs):
    print("processing " + print_func(f, args, kwargs))

对于process(myfunc, 1,2, a="A",b=0),预期输出应为"processing myfunc(1,2,a="A", b=0)"

我已经打印出了args的进展如下:

def print_func(f, *args, **kwarg):
    func_str = f.__name__ + "("
    if len(args) > 0:
        func_str = func_str + (', '.join(['%.2f']*len(x)) % args)
     func_str = func_str + ")"

在上面的示例中,将生成输出processing myfunc(1,2)
我的问题是如何打印kwargs。我无法想出一个类似的解决方案,使用动态格式化字符串将其打印为用","分隔的对序列。
任何建议都将不胜感激。
2个回答

7
为了格式化argskwargs,你可以简单地对它们进行迭代并创建你的字符串表示形式。
def process(my_func, *args, **kwargs):

    #Iterate over all args, convert them to str, and join them
    args_str = ','.join(map(str,args))

    #Iterater over all kwargs, convert them into k=v and join them
    kwargs_str = ','.join('{}={}'.format(k,v) for k,v in kwargs.items())

    #Or using f-strings
    #kwargs_str = ','.join(f'{k}={v}' for k,v in kwargs.items()

    #Form the final representation by adding func name
    return "processing {}({})".format(my_func.__name__, ','.join([args_str,kwargs_str]))

    #Or using f-strings
    #return f"processing {my_func.__name__}({','.join([args_str,kwargs_str])})"

print(process(my_func, 1,2, a="A",b=0))

输出结果将会是:
processing my_func(1,2,a=A,b=0)

1
您可以通过创建类似这样的注释来实现:

def printArgs(my_func):
    def wrapper(*arg, **kwargs):
        print("{}({})".format(my_func.__name__, ','.join([str(arg),str(kwargs)])))
        return my_func(*arg, **kwargs)
    return wrapper

@printArgs
def a_function_where_you_want_to_print_args(arg1, arg2, arg3="arg3"):
    pass

a_function_where_you_want_to_print_args(1,2, arg3="b")

这将打印出 "a_function_where_you_want_to_print_args((1, 2),{'arg3': 'b'})"。

谢谢您的回答,但为了可读性,我更喜欢打印函数参数列表 a (1,2, argg=b)。正如我所提到的,我已经成功使用 args 实现了这一点,但是 kwargs 却没有。 - pablochacin
1
我不明白为什么这个答案被踩了,因为如果可以在任何函数中添加装饰器,它将对调试非常有用。但是有一个细节我不明白:函数内部的代码不起作用吗?(我用print('Inside a_function_where_you_want_to_print_args')替换了pass,但它没有被打印出来) - Giampaolo Ferradini
1
我从一个装饰器教程中得到了答案:在返回包装器之前,您需要从装饰器本身调用传递给装饰器的函数。在这种情况下,在return wrapper之前调用my_func(*arg, **kwargs)即可。再次感叹,这是一个非常优美的解决方案。 - Giampaolo Ferradini

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接