我正在处理一个包含子包和每个子包中的几个模块的包。 大多数函数需要在" main"中启动的几个参数(~10)。功能。通常,所有参数都传递给从函数内调用的方法。传递这些参数的最佳方法是什么?
考虑以下情况:
def func(arg1, arg2, ...., argn):
do something
ext_method(arg1, arg3,...argk) # Note: all the arguments are not passed to ext_method
cleanup
PS:函数嵌套可以很深(比如从主函数开始大约10-12个函数)。 我考虑了两种选择:
Inspect方法:使用所有参数构造main函数中所有参数的dict。调用函数:使用inspect包中的方法获取其argspec,并从" global"中过滤出不必要的参数。争论。它看起来像下面的代码片段。
args = {arg1: obj1, arg2:obj2,...}
req_args = dict([(k, v) for k, v in args.items() if k in inspect.getargspec(ext_method).args])
键值方法:使用参数键值对
调用ext_method()
ext_method(arg1=val1, arg3=val3,...,argk=valk)
我发现第二种方法无效,因为随着更多功能被添加到包中,ext_method()
的签名变得不容易。方法1是更好的选择吗?
答案 0 :(得分:14)
更多,更好的选择:
将**kwargs
添加到您的函数中,忽略额外参数:
ex_method(arg1, arg2, **kw)
将所有参数作为属性传递给对象;一个namedtuple
class在这里是理想的。每个函数只使用它需要的那些属性。
我会选择后者。停止移动10个参数,开始绕过一个。
更好的是,如果所有这些操作都与这些参数所代表的数据真正耦合,那么您可能应该使用类来代替:
class SomeConcept(object):
def __init__(self, arg1, arg2, arg3, .., argN):
self.arg1 = arg1
# ... etc.
def operation1(self, external_argument):
# use `self` attributes, return something.
而不是所有这些单独的功能。
答案 1 :(得分:5)
要传递多个参数,请使用*
运算符和**
运算符。
def foo(*arg, **karg):
print arg, karg
*
运算符包中包含所有有序参数,**
运算符包含其中所有不匹配的键参数。
例如:
def foo(a, *arg):
return a, arg
foo(1,2,3)
>> (1, [2, 3])
foo(1)
>> (1, [])
对于关键参数,它的工作方式相同,
def foo(a=1, b=2, **kargs):
return a, b, kargs
foo(2, c=10, b=23)
>> (2, 23, {'c': 10})
然后你可以将它们混合起来,那些特殊情况总是在签名的末尾如下:
def foo(a, c, d=4, *arg, **karg):
return a, c, d, arg, karg
foo(1, 2)
>> (1, 2, 4, [], {})
foo(1,2,3)
>> (1, 2, 3, [], {})
foo(1, 2, 3, 4, 5)
>> (1, 2, 3, [4, 5], {})
foo(1, 2, h=2, f=3, d=4, j=3)
>> (1, 2, 4, [], {'h': 2, 'f': 3, 'j': 3})
foo(1,2,3,4,5, o=2)
>> (1, 2, 3, [4 ,5], {'o': 2})
如果要将dict作为参数或参数列表传递给函数,也可以使用这些运算符:
a = [1,2,3]
b = {'c': 1, 'd': 3}
def foo(a, b, *arg, **karg):
return a, b, arg, karg
foo(*a, **b)
>> (1, 2, [3], {'c': 1, 'd': 3})