我正在开发一个包含子包和每个子包中的几个模块的包.大多数函数需要在"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
Run Code Online (Sandbox Code Playgroud)
PS:函数嵌套可以很深(比如从主函数开始大约10-12个函数).我考虑过两种选择:
Inspect方法:使用所有参数构造main函数中所有参数的dict.调用函数:使用inspect包中的方法获取其argspec,并从"全局"参数dict中过滤掉不必要的参数.它看起来像下面的代码片段.
args = {arg1: obj1, arg2:obj2,...}
req_args = dict([(k, v) for k, v in args.items() if k in inspect.getargspec(ext_method).args])
Run Code Online (Sandbox Code Playgroud)键值方法:ext_method()使用参数键值对调用
ext_method(arg1=val1, arg3=val3,...,argk=valk)
Run Code Online (Sandbox Code Playgroud)我发现第二种方法无效,因为ext_method()随着更多功能被添加到包中而不易改变签名.方法1是更好的选择吗?
Mar*_*ers 15
更多,更好的选择:
添加**kwargs到您的函数并忽略额外的参数:
ex_method(arg1, arg2, **kw)
Run Code Online (Sandbox Code Playgroud)使用所有参数作为属性传递对象; 一namedtuple堂课在这里很理想.每个函数仅使用它需要的那些属性.
我会选择后者.停止移动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.
Run Code Online (Sandbox Code Playgroud)
而不是所有那些单独的功能.
要传递多个参数,请使用*运算符和**运算符。
def foo(*arg, **karg):
print arg, karg
Run Code Online (Sandbox Code Playgroud)
该*运营商包中的所有命令参数,以及**运营商包所有不匹配的关键参数在里面。
例如:
def foo(a, *arg):
return a, arg
foo(1,2,3)
>> (1, [2, 3])
foo(1)
>> (1, [])
Run Code Online (Sandbox Code Playgroud)
对于关键参数,其工作方式相同,
def foo(a=1, b=2, **kargs):
return a, b, kargs
foo(2, c=10, b=23)
>> (2, 23, {'c': 10})
Run Code Online (Sandbox Code Playgroud)
然后,您可以将它们混合在一起,这些分隔符始终位于签名的末尾,如下所示:
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})
Run Code Online (Sandbox Code Playgroud)
如果要将字典作为参数或参数列表传递给函数,也可以使用这些运算符:
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})
Run Code Online (Sandbox Code Playgroud)