0

因此,如果我有一个带有大量命名参数的函数:

def foo(a = 1, b = 2, c = 3, d = 4, e = 5) # etc...
    pass

我用与定义中的名称完全相同的所有参数来调用它:

a = 0
b = 0
c = 0
d = 0
e = 0

有没有办法避免这样做?

foo(e = e, b = b, d = d, a = a, c = c)

并这样做:

foo(e, b, d, a, c)

?

我想我可以这样做:

foo(a, b, c, d, e)

但是如果参数名称很复杂,我记不起它们的顺序怎么办?

4

5 回答 5

5

好吧,您可以执行以下操作:

def foo(a, b, c, d):
    print a, b, c, d


d = 4
b = 2
c = 3
a = 1

import inspect
foo(*[locals().get(arg, None) for arg in inspect.getargspec(foo).args])

但我不确定我是否可以推荐这个......在实践中我会使用一个参数字典:

foo_params = {
    'd' : 4,
    'b' : 2,
    'c' : 3,
    'a' : 1
}

foo(**foo_params)

编写一个foo使用较少参数的包装器。

于 2012-04-05T16:50:28.067 回答
3

如果更改函数不是您的选择,但您可以自由更改为传递的参数分配值的方法,这里有一个示例代码,可能对您有所帮助。这使用 orderdict 来保存

给定

>>> def foo(a = 1, b = 2, c = 3, d = 4, e = 5):
    print "a={0},b={1},c={2},d={3},e={4}".format(a,b,c,d,e)

你能做的

>>> var=dict()
>>> var['c']=12
>>> var['a']=10
>>> var['b']=11
>>> var['e']=14
>>> foo(**var)
a=10,b=11,c=12,d=4,e=14

请注意,此答案类似于@thg435 提出的答案,但您是

  1. 不使用检查来破解函数期望的参数。
  2. 不查看本地/全局字典。
  3. 支持默认为默认参数的缺失参数。
  4. 当然,您不必记住顺序。
  5. 而且您甚至不必将变量作为参数传递。只是通过字典。
于 2012-04-05T17:12:03.907 回答
3

Python 的参数传递机制非常灵活。如果它们不够灵活,这对我来说似乎是一种设计气味......

  • 可能的气味:函数的参数太多。解决方案:拆分为多个函数,在字典或对象中一起传递一些 args。

  • 可能的气味:错误的变量名。解决方案:给变量起更具描述性的名称。

或者只是咬紧牙关,找出正确的顺序,并保持简单。

于 2012-04-05T16:53:38.507 回答
0

Calling a 5-argument function with a completely different set of arguments each time is pretty rare. If, in practice, you're using the same a, c, and e args most of the time and calling with different b and d args (for example), you can create a class to help you with this:

class FooWrapper(object):
    def __init__( self, commonA, commonC, commonE ):
        self.a = commonA
        self.c = commonC
        self.e = commonE

    def invokeFoo( self, _b, _d ):
        foo( a=self.a, b = _b, c = self.c, d = _d, e = self.e )

w = FooWrapper( 1, 2, 3 )
w.invokeFoo( 4, 5 )          # calls foo( 1, 4, 2, 5, 3 )
w.invokeFoo( 6, 7 )          # calls foo( 1, 6, 2, 7, 3 )
于 2012-04-05T18:00:55.270 回答
0

您可以执行以下操作:

def func(a=1, b=2, c=3, **kw):
    print a,b,c

a = 11
b = 22
c = 33

func(**locals())
于 2012-04-05T16:51:23.057 回答