首页 > 解决方案 > 动态调用参数大小未知的函数

问题描述

我正在尝试向我正在编写的脚本引入一些自动化,并且在调用具有来自另一个模块的参数的函数时遇到了一些麻烦。这是场景:

我有两个模块:test.py 和 Strategies.py。我有生成 Strategies.py 中所有函数列表的代码。从该列表中,我使用 getattr 来执行每个函数。

我遇到的问题是我的一些函数有参数。使用具有“x”参数的函数出现以下错误:

TypeError: buy_test_function() missing 1 required positional argument: 'x'

为了尽可能清楚地说明这一点,以下是相关代码:

call_method = strategy_names[0][y]
call_method = getattr(Strategies, call_method)()

我知道上面的第一行工作正常。我也知道是第二行末尾的空括号导致了问题。我需要的魔法是找到一种方法来动态读取每个函数所需的参数并使用括号中的必要参数执行函数。

我尝试使用inspect.signature(),但它一直告诉我该对象不可调用。

我不得不相信 Python 对此有一个优雅的解决方案,但我在 Google 上运气不佳。非常感谢任何帮助。

谢谢!

标签: python

解决方案


假设 Strategies 中的函数不是类方法,并且您已经在签名中注释了函数类型,您可以构造您为参数指定的类类型的默认实例并将它们作为参数传递:

from inspect import signature
call_method = strategy_names[0][y]
call_method = getattr(Strategies, call_method)
sig = signature(call_method)
call_method = getattr(Strategies, call_method)(*[param.annotation() for param in sig.parameters.values()])

见参考:

>>> def test(x:int):
...    return x*2
>>> sig = signature(test)
>>> sig.parameters['x'].annotation
<class 'int'>
>>> sig.parameters['x'].annotation()
0
>>> test(*[param.annotation() for param in sig.parameters.values()])
0

我还要注意,如果您可以提前为给定方法定义要在调用方法中使用的值,并且 Strategies 中的函数名称是唯一的,则可以预先构建一个字典,将函数名称映射到您想要的 args使用:

args = {'test':[1]}
test(*args[test.__name__])

推荐阅读