gpt4 book ai didi

python - 如何通过装饰器获取底层函数参数信息?

转载 作者:行者123 更新时间:2023-12-01 05:41:13 26 4
gpt4 key购买 nike

我编写get_function_arg_data(func)如下代码来获取函数func的参数信息:

def get_function_arg_data(func):
import inspect
func_data = inspect.getargspec(func)
args_name = func_data.args #func argument list
args_default = func_data.defaults #funcargument default data list
return args_name, args_default


def showduration(user_function):
''' show time duration decorator'''
import time
def wrapped_f(*args, **kwargs):
t1 = time.clock()
result = user_function(*args, **kwargs)
print "%s()_Time: %0.5f"%(user_function.__name__, time.clock()-t1)
return result
return wrapped_f


def foo(para1, para2=5, para3=7):
for i in range(1000):
s = para1+para2+para3
return s

@showduration
def bar(para1, para2, para3):
for i in range(1000):
s=para1+para2+para3
return s

print get_function_arg_data(foo)
bar(1,2,3)
print get_function_arg_data(bar)


>>>
(['para1', 'para2', 'para3'], (5, 7))
bar()_Time: 0.00012
([], None)
>>>

get_function_arg_data() 适用于 foo,不适用于 bar,因为 bar 由装饰器 @showduration 装饰。我的问题是如何穿透装饰器来获取底层函数的信息(参数列表和默认值)?

感谢您的提示。

最佳答案

我认为不存在或至少不知道有任何通用方法可以“穿透”修饰函数并获取底层函数的信息,因为 Python 的函数修饰概念非常 -- 事实上,一般来说,没有任何东西要求或保证原始函数将被调用(尽管通常是这种情况)。

因此,一个更实际的问题是:我如何编写自己的装饰器来检查底层函数的参数信息?

之前建议的一种简单方法是使用 Michele Simionato 的 decorator模块(并编写与其兼容的装饰器)。

一种不太健壮但极其简单的方法是根据您问题中的代码执行如下所示的操作:

def get_function_arg_data(func):
import inspect
func = getattr(func, '_original_f', func) # use saved original if decorated
func_data = inspect.getargspec(func)
args_name = func_data.args #func argument list
args_default = func_data.defaults #funcargument default data list
return args_name, args_default

def showduration(user_function):
'''show time duration decorator'''
import time
def wrapped_f(*args, **kwargs):
t1 = time.clock()
result = user_function(*args, **kwargs)
print "%s()_Time: %0.5f"%(user_function.__name__, time.clock()-t1)
return result
wrapped_f._original_f = user_function # save original function
return wrapped_f

def foo(para1, para2=5, para3=7):
for i in range(1000):
s = para1+para2+para3
return s

@showduration
def bar(para1, para2, para3):
for i in range(1000):
s=para1+para2+para3
return s

print 'get_function_arg_data(foo):', get_function_arg_data(foo)
print 'get_function_arg_data(bar):', get_function_arg_data(bar)

所有修改涉及的是将原始函数保存在名为 _original_f 的属性中,该属性添加了装饰器返回的包装函数。然后,get_function_arg_data() 函数只是检查此属性,并根据其值而不是传递给它的修饰函数返回信息。

虽然这种方法不适用于任何修饰函数,仅适用于添加了特殊属性的函数,但它与 Python 2 和 3 兼容。

所示代码产生的输出:

get_function_arg_data(foo): (['para1', 'para2', 'para3'], (5, 7))
get_function_arg_data(bar): (['para1', 'para2', 'para3'], None)

关于python - 如何通过装饰器获取底层函数参数信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17499693/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com