如何设置和调用具有不同参数组合的函数
How to set and call a function with different combinations of parameters
我有一个 python 程序(或函数),我想用不同的参数值来调用它。
假设函数是:
myfunc(x = 0,y = 0,z =0, w=0, ...):
我使用这样的命令行来设置参数:
run x=2#3#4--y=1#2--z=5
它显示了 x、y 和 z 的值(参数的数量不固定,许多可能有默认值,我想设置任意一组)。我想用 x=2, y=1, z=5
等所有组合调用该函数。对于此示例,有 6 种组合。
我试着用循环来写它,但我认为它必须递归地写,因为在循环中我不知道什么时候为下一个 运行.
设置和取消设置变量
all_vars = var.split("--")
cont = True
while cont:
ii = 0
for _var in all_vars:
_var_name,_var_item_list = _var.split("=")
_var_item_list = _var_item_list.split("#")
cont = False
for var_item in _var_item_list:
if not _var_name in args or args[_var_name] != var_item
args[_var_name] = var_item
_output_name += "_" + _var_name + "_" + str(var_item)
cont = True
ii += 1
break
else:
continue
if cont and ii == len(all_vars):
ctx.invoke(run, **args) # calling the function
你可以这样做并且没有库:
var = "x=2#3#4--y=1#2--z=5"
var = {var_bloc[:var_bloc.index("=")]: var_bloc[var_bloc.index("=")+1:].split("#") for var_bloc in var.split("--")}
#Here var will be {"x":['2', '3', '4'], "y": ['1', '2'], "z": ['5']}
def enumerate_possibility(params):
if len(params) == 1:
for k, possible_values in params.items():
for val in possible_values:
yield {k:val}
else:
key, possible_values = list(params.items())[0]
for val in possible_values:
for item in enumerate_possibility({k:v for k, v in params.items() if k != key}):
yield {key:val, **item}
for possible_param in enumerate_possibility(var):
myfunc(**possible_param)
我认为你可以通过以下方式做到这一点
import itertools
import inspect
def fun(x,y,z, d=3):
print(x,y,z)
return x+y+z
params = inspect.signature(fun).parameters # paramters of your function
a = "x=2#3#4--y=1#2--z=5".split("--")
var_names = [x.split("=")[0] for x in a]
values = [map(int, x.split("=")[1].split("#")) for x in a]
tot_comb = [dict(zip(var_names, comb)) for comb in itertools.product(*values)]
for comb in tot_comb:
print(fun(**comb))
如果你想检查你的函数是否可以使用给定的关键字参数调用,我已经包含了用例的检查模块
我通常在测试场景中这样做,但使用 pytest:
@pytest.mark.parametrize('bar', ['a', 'b', 'c'])
@pytest.mark.parametrize('_x', [1, 2, 3])
def test_foo(bar:str, _x: int):
print(bar, _x)
此代码将使用所有参数组合执行函数测试:
============================= test session starts ==============================
collecting ... collected 9 items
test_static_models.py::test_foo[1-a]
test_static_models.py::test_foo[1-b]
test_static_models.py::test_foo[1-c]
test_static_models.py::test_foo[2-a]
test_static_models.py::test_foo[2-b]
test_static_models.py::test_foo[2-c]
test_static_models.py::test_foo[3-a]
test_static_models.py::test_foo[3-b]
test_static_models.py::test_foo[3-c]
我有一个 python 程序(或函数),我想用不同的参数值来调用它。
假设函数是:
myfunc(x = 0,y = 0,z =0, w=0, ...):
我使用这样的命令行来设置参数:
run x=2#3#4--y=1#2--z=5
它显示了 x、y 和 z 的值(参数的数量不固定,许多可能有默认值,我想设置任意一组)。我想用 x=2, y=1, z=5
等所有组合调用该函数。对于此示例,有 6 种组合。
我试着用循环来写它,但我认为它必须递归地写,因为在循环中我不知道什么时候为下一个 运行.
设置和取消设置变量 all_vars = var.split("--")
cont = True
while cont:
ii = 0
for _var in all_vars:
_var_name,_var_item_list = _var.split("=")
_var_item_list = _var_item_list.split("#")
cont = False
for var_item in _var_item_list:
if not _var_name in args or args[_var_name] != var_item
args[_var_name] = var_item
_output_name += "_" + _var_name + "_" + str(var_item)
cont = True
ii += 1
break
else:
continue
if cont and ii == len(all_vars):
ctx.invoke(run, **args) # calling the function
你可以这样做并且没有库:
var = "x=2#3#4--y=1#2--z=5"
var = {var_bloc[:var_bloc.index("=")]: var_bloc[var_bloc.index("=")+1:].split("#") for var_bloc in var.split("--")}
#Here var will be {"x":['2', '3', '4'], "y": ['1', '2'], "z": ['5']}
def enumerate_possibility(params):
if len(params) == 1:
for k, possible_values in params.items():
for val in possible_values:
yield {k:val}
else:
key, possible_values = list(params.items())[0]
for val in possible_values:
for item in enumerate_possibility({k:v for k, v in params.items() if k != key}):
yield {key:val, **item}
for possible_param in enumerate_possibility(var):
myfunc(**possible_param)
我认为你可以通过以下方式做到这一点
import itertools
import inspect
def fun(x,y,z, d=3):
print(x,y,z)
return x+y+z
params = inspect.signature(fun).parameters # paramters of your function
a = "x=2#3#4--y=1#2--z=5".split("--")
var_names = [x.split("=")[0] for x in a]
values = [map(int, x.split("=")[1].split("#")) for x in a]
tot_comb = [dict(zip(var_names, comb)) for comb in itertools.product(*values)]
for comb in tot_comb:
print(fun(**comb))
如果你想检查你的函数是否可以使用给定的关键字参数调用,我已经包含了用例的检查模块
我通常在测试场景中这样做,但使用 pytest:
@pytest.mark.parametrize('bar', ['a', 'b', 'c'])
@pytest.mark.parametrize('_x', [1, 2, 3])
def test_foo(bar:str, _x: int):
print(bar, _x)
此代码将使用所有参数组合执行函数测试:
============================= test session starts ==============================
collecting ... collected 9 items
test_static_models.py::test_foo[1-a]
test_static_models.py::test_foo[1-b]
test_static_models.py::test_foo[1-c]
test_static_models.py::test_foo[2-a]
test_static_models.py::test_foo[2-b]
test_static_models.py::test_foo[2-c]
test_static_models.py::test_foo[3-a]
test_static_models.py::test_foo[3-b]
test_static_models.py::test_foo[3-c]