Python:使用长参数列表处理函数的最佳方法?

时间:2013-06-21 11:28:40

标签: python python-2.7

我已经找到了关于如何将长参数列表传递给函数的各种详细解释,但我仍然怀疑这是否是正确的方法。

换句话说,我怀疑我做错了,但我看不出怎么做正确

问题:我有(不是很长)循环函数,它使用了很多变量,需要修改至少其中一些内容。

我最终得到的是这样的:

def myFunction(alpha, beta, gamma, zeta, alphaList, betaList, gammaList, zetaList):
    <some operations>
    myFunction(alpha, beta, modGamma, zeta, modAlphaList, betaList, gammaList, modZetaList)

...我希望看到我对原始变量所做的更改(在C中我只会传递一个引用,但我听说在Python中它总是一个副本?)。

对不起,如果菜鸟,我不知道如何说出这个问题,以便找到相关的答案。

7 个答案:

答案 0 :(得分:2)

您可以将所有参数包装在一个类中,如下所示:

class FooParameters:
    alpha = 1.0
    beta = 1.0
    gamma = 1.0
    zeta = 1.0
    alphaList = []
    betaList = []
    gammaList = []
    zetaList = []

然后你的函数接受一个参数实例:

def myFunction(params):
    omega = params.alpha * params.beta + exp(params.gamma)
    # more magic...

呼叫:

testParams = FooParameters()
testParams.gamma = 2.3
myFunction(testParams)
print params.zetaList

因为params实例是由引用传递的,所以保留了函数的更改。

答案 1 :(得分:2)

这通常用于matplotlib。他们使用***传递了很长的参数列表,例如:

def function(*args, **kwargs):
    do something

通话功能:

function(1,2,3,4,5, a=1, b=2, b=3)

此处1,2,3,4,5将转到argsa=1, b=2, c=3将转到kwargs,作为字典。这样他们就可以达到你的功能:

args = [1,2,3,4,5]
kwargs = {a:1, b:2, c:3}

你可以按照自己想要的方式对待它们。

答案 2 :(得分:1)

我不知道Python在传递给函数时复制值的想法。那根本不是是真的。

相反:函数中的每个参数都是一个引用原始对象的附加名称。如果以某种方式更改该对象的值 - 例如,如果它是一个列表并且您更改了其中一个成员 - 那么原始对象也会看到该更改。但是,如果你将名称重新绑定其他东西 - 比如做alpha = my_completely_new_value - 那么原件就会保持不变。

答案 3 :(得分:1)

你可能会想到类似于此的东西:

def myFunction(*args):
    var_names = ['alpha','beta','gamma','zeta']
    locals().update(zip(var_names,args))
    myFunction(alpha,beta,gamma,zeta)

然而,这种'经常'是行不通的。我建议引入另一个命名空间:

from collections import OrderedDict
def myFunction(*args):
    var_names = ['alpha','beta','gamma','zeta']
    vars = OrderedDict(zip(var_names,args))

    #get them all via vars[var_name]

    myFunction(*vars.values()) #since we used an orderedDict we can simply do *.values()

答案 4 :(得分:1)

您可以在闭包中捕获未修改的值:

def myFunction(alpha, beta, gamma, zeta, alphaList, betaList, gammaList, zetaList):
    def myInner(g=gamma, al, zl):
        <some operations>
        myInner(modGamma, modAlphaList, modZetaList)
    myInner(al=alphaList, zl=zetaList)

(顺便说一句,这是在Python中编写真正的递归函数的唯一方法。)

答案 5 :(得分:0)

您可以传入字典并返回新字典。或者将你的方法放在一个类中,并将alpha,beta等作为属性。

答案 6 :(得分:0)

你应该把myFunction放在一个班级里。使用适当的属性设置类并调用相应的函数。这个州很好地包含在课堂上。