调用参数数量未知的函数
Calling function with unknown number of parameters
我正在尝试在 python 中创建一组函数,它们将对一组输入执行类似的操作。所有函数都有一个固定的输入参数,其中一半还需要第二个参数。为了简单起见,下面是一个只有两个功能的玩具示例。
现在,我想在我的脚本中 运行 适当的函数,这取决于用户输入的数字。在这里,用户是随机函数(因此最小示例有效)。我想做的是这样的:
def function_1(*args):
return args[0]
def function_2(*args):
return args[0] * args[1]
x = 10
y = 20
i = random.randint(1,2)
f = function_1 if i==1 else function_2
return_value = f(x,y)
它有效,但对我来说似乎很乱。我宁愿将 function_1
定义为
def function_1(x):
return x
另一种方法是定义
def function_1(x,y):
return x
但这给我留下了悬空的 y
参数。
但这并不容易。我的方法是 "proper" 解决问题的方法还是有更好的方法?
您可能还有一个带有可选第二个参数的函数:
def function_1(x, y = None):
if y != None:
return x + y
else:
return x
这是示例 运行:
>>> function_1(3)
3
>>> function_1(3, 4)
7
甚至可选的多个参数!看看这个:
def function_2(x, *args):
return x + sum(args)
样本运行:
>>> function_2(3)
3
>>> function_2(3, 4)
7
>>> function_2(3, 4, 5, 6, 7)
25
列表可参考args
:
def function_3(x, *args):
if len(args) < 1:
return x
else:
return x + sum(args)
样本运行:
>>> function_3(1,2,3,4,5)
15
这里有几种方法,它们都添加了更多样板代码。
还有这个PEP你可能会感兴趣
但是 'pythonic' 这样做的方式不像通常的函数重载那样优雅,因为函数只是 class 属性。
所以你可以选择这样的功能:
def foo(*args):
然后数一数你有多少 args
这将非常广泛但也非常灵活。
另一种方法是默认参数:
def foo(first, second=None, third=None)
不太灵活但更容易预测,最后你还可以使用:
def foo(anything)
并在相应的函数中检测 anything
的类型。
您的猴子修补示例也可以工作,但如果您将它与 class 方法一起使用,它会变得更加复杂,并且确实会使自省变得棘手。
编辑:此外,对于您的情况,您可能希望将函数分开并编写单个 'dispatcher' 函数,该函数将根据参数为您调用适当的函数,考虑到上述情况,这可能是最佳解决方案。
EDIT2:根据您的评论,我相信以下方法可能适合您
def weigh_dispatcher(*args, **kwargs):
#decide which function to call base on args
if 'somethingspecial' in kwargs:
return weight2(*args, **kwargs)
def weight_prep(arg):
#common part here
def weight1(arg1, arg2):
weitht_prep(arg1)
#rest of the func
def weight2(arg1, arg2, arg3):
weitht_prep(arg1)
#rest of the func
或者,您可以将公共部分移动到调度程序中
我正在尝试在 python 中创建一组函数,它们将对一组输入执行类似的操作。所有函数都有一个固定的输入参数,其中一半还需要第二个参数。为了简单起见,下面是一个只有两个功能的玩具示例。
现在,我想在我的脚本中 运行 适当的函数,这取决于用户输入的数字。在这里,用户是随机函数(因此最小示例有效)。我想做的是这样的:
def function_1(*args):
return args[0]
def function_2(*args):
return args[0] * args[1]
x = 10
y = 20
i = random.randint(1,2)
f = function_1 if i==1 else function_2
return_value = f(x,y)
它有效,但对我来说似乎很乱。我宁愿将 function_1
定义为
def function_1(x):
return x
另一种方法是定义
def function_1(x,y):
return x
但这给我留下了悬空的 y
参数。
但这并不容易。我的方法是 "proper" 解决问题的方法还是有更好的方法?
您可能还有一个带有可选第二个参数的函数:
def function_1(x, y = None):
if y != None:
return x + y
else:
return x
这是示例 运行:
>>> function_1(3)
3
>>> function_1(3, 4)
7
甚至可选的多个参数!看看这个:
def function_2(x, *args):
return x + sum(args)
样本运行:
>>> function_2(3)
3
>>> function_2(3, 4)
7
>>> function_2(3, 4, 5, 6, 7)
25
列表可参考args
:
def function_3(x, *args):
if len(args) < 1:
return x
else:
return x + sum(args)
样本运行:
>>> function_3(1,2,3,4,5)
15
这里有几种方法,它们都添加了更多样板代码。
还有这个PEP你可能会感兴趣
但是 'pythonic' 这样做的方式不像通常的函数重载那样优雅,因为函数只是 class 属性。
所以你可以选择这样的功能:
def foo(*args):
然后数一数你有多少 args
这将非常广泛但也非常灵活。
另一种方法是默认参数:
def foo(first, second=None, third=None)
不太灵活但更容易预测,最后你还可以使用:
def foo(anything)
并在相应的函数中检测 anything
的类型。
您的猴子修补示例也可以工作,但如果您将它与 class 方法一起使用,它会变得更加复杂,并且确实会使自省变得棘手。
编辑:此外,对于您的情况,您可能希望将函数分开并编写单个 'dispatcher' 函数,该函数将根据参数为您调用适当的函数,考虑到上述情况,这可能是最佳解决方案。
EDIT2:根据您的评论,我相信以下方法可能适合您
def weigh_dispatcher(*args, **kwargs):
#decide which function to call base on args
if 'somethingspecial' in kwargs:
return weight2(*args, **kwargs)
def weight_prep(arg):
#common part here
def weight1(arg1, arg2):
weitht_prep(arg1)
#rest of the func
def weight2(arg1, arg2, arg3):
weitht_prep(arg1)
#rest of the func
或者,您可以将公共部分移动到调度程序中