当前位置: 首页 > 面试题库 >

装饰器打印函数调用详细信息-参数名称和有效值

沈博延
2023-03-14
问题内容

我想做一个函数,作为另一个函数的装饰器,它将打印该函数调用的详细信息-参数名称和有效值。我当前的实现是这样。

def describeFuncCall(func):
    """
    Decorator to print function call details.

    parameters names and effective values.
    """

    def wrapper(*func_args, **func_kwargs):
        print "func_code.co_varnames =", func.func_code.co_varnames
        print "func_code.co_argcount =", func.func_code.co_argcount
        print "func_args =", func_args
        print "func_kwargs =", func_kwargs
        params = []
        for argNo in range(func.func_code.co_argcount):
            argName = func.func_code.co_varnames[argNo]
            argValue = (
                func_args[argNo]
                if argNo < len(func_args)
                else func.func_defaults[argNo - func.func_code.co_argcount]
            )
            params.append((argName, argValue))
        for argName, argValue in func_kwargs.items():
            params.append((argName, argValue))
        params = [argName + " = " + repr(argValue)
                  for argName, argValue in params]
        print (func.__name__ + " ( " + ", ".join(params) + " )")
        return func(*func_args, **func_kwargs)

    return wrapper


@describeFuncCall
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)

Kinda可以工作,但是有一些错误:

致电

test(1, 2, 3, 4, 5, d = 6, g = 12.9)

它打印

test ( a = 1, b = 2, c = 3, d = 6, g = 12.9 )

预期的结果是

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

我被困在这里。您能帮我找到正确的解决方案吗?


问题答案:

对不起,有点混乱。我从http://wiki.python.org/moin/PythonDecoratorLibrary#Easy_Dump_of_Function_Arguments修改了一些代码

def dump_args(func):
    "This decorator dumps out the arguments passed to a function before calling it"
    argnames = func.func_code.co_varnames[:func.func_code.co_argcount]
    fname = func.func_name
    def echo_func(*args,**kwargs):
        print fname, "(", ', '.join(
            '%s=%r' % entry
            for entry in zip(argnames,args[:len(argnames)])+[("args",list(args[len(argnames):]))]+[("kwargs",kwargs)]) +")"
    return echo_func

@dump_args
def test(a, b = 4, c = 'blah-blah', *args, **kwargs):
    pass

测试(1、2、3、4、5,d = 6,g = 12.9)

输出:

测试(a = 1,b = 2,c = 3,args = [4,5],kwargs = {‘d’:6,’g’:12.9})



 类似资料:
  • #include <stdio.h> int func(int a, int b) { int c = a * b; printf("c is %d\n", c); } int main(void) { func(1, 2); return 0; } 技巧 使用gdb调试程序时,可以使用“i frame”命令(i是info命令缩写)显示函数堆栈帧信息。以上面程

  • 是否可以通过路由的名称(如控制器和它使用的操作名称)获取路由的详细信息? 我浏览了文档,它只列出了当前路由的功能,即,等。是否可以通过别名/名称获得特定路由、操作和控制器的详细信息?

  • 问题 你写了一个装饰器作用在某个函数上,但是这个函数的重要的元信息比如名字、文档字符串、注解和参数签名都丢失了。 解决方案 任何时候你定义装饰器的时候,都应该使用 functools 库中的 @wraps 装饰器来注解底层包装函数。例如: import time from functools import wraps def timethis(func): ''' Decorato

  • 主要内容:带参数的函数装饰器,函数装饰器可以嵌套前面章节中,我们已经讲解了 Python 内置的 3 种函数装饰器,分别是 @staticmethod、@classmethod 和 @property,其中 staticmethod()、classmethod() 和 property() 都是 Python 的内置函数。 那么,函数装饰器的工作原理是怎样的呢?假设用 funA() 函数装饰器去装饰 funB() 函数,如下所示: 实际上,上面

  • 问题 你想在装饰器中给被包装函数增加额外的参数,但是不能影响这个函数现有的调用规则。 解决方案 可以使用关键字参数来给被包装函数增加额外参数。考虑下面的装饰器: from functools import wraps def optional_debug(func): @wraps(func) def wrapper(*args, debug=False, **kwargs):