
通过inspect获取装饰器参数的难题
在python中,inspect模块提供了获取函数元数据的方法。然而,获取装饰器传入的参数却并非易事。
以以下代码为例:
import inspect
from functools import wraps
def task(_id, params):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
return decorator
@task(_id="aaa", params=(1,2,3))
def foo(q=1):
...
if __name__ == '__main__':
print(inspect.getclosurevars(foo.__wrapped__).nonlocals) # 不生效,期望获取(_id="aaa", params=(1,2,3))信息使用inspect.getclosurevars获取闭包变量不起作用,因为装饰器内部定义的变量不在foo.__wrapped__的闭包中。
立即学习“Python免费学习笔记(深入)”;
解决方案
inspect无法直接获取装饰器参数,目前有以下变通方案:
1. 在装饰器内部存储参数
在decorator函数中显式存储参数,然后在包装器函数中使用它们。
2. 使用ast解析代码
使用ast模块解析装饰器的代码,并提取参数。不过,这种方法仅适用于特定类型的代码,缺乏通用性。
示例代码:
import ast
def get_decorator_args(func):
source = inspect.getsource(func)
tree = ast.parse(source)
for node in ast.walk(tree):
if isinstance(node, ast.FunctionDef):
for decorator in node.decorator_list:
if isinstance(decorator, ast.Call) and decorator.func.id == "task":
args = {
arg.arg: ast.literal_eval(arg.value)
for arg in decorator.keywords
}
return args
return {}
print(get_decorator_args(foo))
# {'_id': 'aaa', 'params': (1, 2, 3)}需要注意的是,该解决方案仅适用于上述特定代码片段。对于更复杂的装饰器,可能需要定制化的解析代码。
以上就是Python装饰器参数如何通过inspect模块获取?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号