【问题标题】:Way to pass multiple parameters to a function in python将多个参数传递给python中的函数的方法
【发布时间】:2012-11-13 05:23:54
【问题描述】:

我编写了一个调用函数的 python 脚本。该函数将 7 个列表作为函数内部的参数,如下所示:

def WorkDetails(link, AllcurrValFound_bse, AllyearlyHLFound_bse, 
                AlldaysHLFound_bse, AllvolumeFound_bse, 
                AllprevCloseFound_bse, AllchangePercentFound_bse, 
                AllmarketCapFound_bse):

除了link 之外的所有参数都是列表。但这使我的代码看起来很丑陋。我将这些列表传递给此函数,因为该函数在所有这些列表中附加了很少的值。我怎样才能以对其他用户更易读的方式做到这一点?

【问题讨论】:

  • 它是在每个列表中添加相同的东西还是不同的东西?

标签: python python-2.7 parameters parameter-passing


【解决方案1】:

测试功能:

您可以使用*args 表示的多个参数和**kwargs 表示的多个关键字并传递给函数:

def test(*args, **kwargs):
    print('arguments are:')
    for i in args:
        print(i)

    print('\nkeywords are:')
    for j in kwargs:
        print(j)

示例:

然后使用任何类型的数据作为参数,并使用尽可能多的参数作为函数的关键字。该函数将自动检测它们并将它们分隔为参数和关键字:

a1 = "Bob"      #string
a2 = [1,2,3]    #list
a3 = {'a': 222, #dictionary
      'b': 333,
      'c': 444}

test(a1, a2, a3, param1=True, param2=12, param3=None)

输出:

arguments are:
Bob
[1, 2, 3]
{'a': 222, 'c': 444, 'b': 333}

keywords are:
param3
param2
param1

【讨论】:

    【解决方案2】:

    你可以改成:

    def WorkDetails(link, details):
    

    然后调用它:

    details = [ AllcurrValFound_bse, AllyearlyHLFound_bse, 
                AlldaysHLFound_bse, AllvolumeFound_bse, 
                AllprevCloseFound_bse, AllchangePercentFound_bse, 
                AllmarketCapFound_bse ]
    workDetails(link, details)
    

    您可以通过以下方式从细节中获取不同的值:

    AllcurrValFound_bse = details[0]
    AllyearlyHLFound_bse = details[1]
    ...
    

    details 转换为字典会更健壮,以变量名作为键,因此请在多行代码与防御性编程之间进行选择=p

    【讨论】:

      【解决方案3】:

      如果您不需要在列表中使用名称,则可以使用 *args

      def WorkDetails(link, *args):
          if args[0] == ... # Same as if AllcurrValFound_bse == ...
              ...
      
       # Call the function:
       WorkDetails(link, AllcurrValFound_bse, AllyearlyHLFound_bse, AlldaysHLFound_bse, AllvolumeFound_bse, AllprevCloseFound_bse, AllchangePercentFound_bse, AllmarketCapFound_bs)
      

      或者你可以使用字典

      def WorkDetails(link, dict_of_lists):
          if dict_of_lists["AllcurrValFound_bse"] == ...
              ...
      
      # Call the function
      myLists = {
          "AllcurrValFound_bse": AllcurrValFound_bse,
          "AllyearlyHLFound_bse": AllyearlyHLFound_bse,
          ...,
          ...
      }
      WorkDetails(link, myLists)
      

      【讨论】:

      • 口红涂在猪身上,OP应该定义一个封装参数的新类
      • 在这些情况下collections.namedtuple 可能会变得有用。
      【解决方案4】:

      我认为使用 **kwarg 更好。 看这个例子:

      def MyFunc(**kwargs):
          print kwargs
      
      
      MyFunc(par1=[1],par2=[2],par3=[1,2,3])
      

      【讨论】:

        【解决方案5】:

        通常不建议向函数传递超过 3 个参数。这不是特定于 python,而是一般的软件设计。您可以阅读有关如何减少传递给函数here 的参数数量的更多信息。

        从以前的答案的角度来看,但从更一般的角度来看,我想补充一点,有几种方法可以使您的代码更具可读性:

        • 将您的函数划分为具有较少参数的更简单的函数(定义一个接受变量linkspecific_listlist_type 的函数。通过这样做,您可以在WorkDetails 函数中检测您传递的列表使用list_type 并将正确的元素添加到specific list)
        • 创建传递给您的函数的参数对象/数据结构(这是先前使用listsdictionaries...的答案所建议的)

        希望对您有所帮助。

        【讨论】:

          【解决方案6】:

          您需要传递这么多列表表明您的函数不只做一件事,您应该通过将其分解为更小的函数和/或将其转换为类来重构它。您可以将参数作为关键字传递,或者将任意数量的参数传递给函数,如this StackOverflow page 所述,但如果您的函数不止一件事,其他人仍然难以阅读和理解。

          【讨论】:

            猜你喜欢
            • 2021-11-11
            • 2014-03-08
            • 2015-11-12
            • 2013-06-28
            • 1970-01-01
            • 2011-04-20
            • 2011-08-18
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多