我想做一个函数,作为另一个函数的装饰器,它将打印该函数调用的细节-参数名和有效值。
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)
挺管用的,不过有一些小问题:
供调用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} )
我被困在这里了。你能帮我找到正确的解决方案吗?
6条答案
按热度按时间x6h2sr281#
以下是Python 3.6+的更新版本
旧版本
使用默认值的工作版本:
结果:
6mw9ycah2#
对不起,有点乱。我修改了一些代码从轻松转储函数参数在PythonDecoratorLibrary。
输出:
kzipqqlq3#
下面是我在Python 3中解决这个问题的方法,基于aliteralmind's答案,如果我可以这么说的话,放得更干净(PEP 8)。清理的大部分灵感来自(当前)accepted answer by Robert King。
代码(
test.py
):输出:
当我获得了“时间和能量”这类神奇的资源时,我对
LOG_FORMAT
很感兴趣,并想知道如何用函数调用的文件名和行号来替换wrapper
子字符串=)编辑(2020年6月11日):修复了@Gahan评论(日期:2020年6月10日)提示后的
wrapper
问题。似乎不可能(参考https://stackoverflow.com/a/8339710/1503549)让一个 Package 器报告(通过
logging
模块)被 Package /修饰的函数的行号。也许wrapt可以用于此目的?aij0ehis4#
@warvariuc的答案,升级到Python 3:
vcudknz35#
下面是一个同样适用于本机函数的版本(只适用于Python 3)
我可以在模块级别激活它,如下所示:
__init__.py
我得到的输出是这样的:
有关包括返回值、输出参数和花哨输出的更完整版本,请参见this gist
mqkwyuun6#
这是一个有点老的职位,但想添加我的位。解决方案所给的warvariuc并不适用于所有情况。如果一个方法有默认值,以及我们发送命名参数,而调用,它不会给出正确的输出。例如,我们得到两个值的b。
添加我修改过的代码。
产出