【问题标题】:Python passing arguments through a chain of function callsPython 通过函数调用链传递参数
【发布时间】:2018-07-18 00:22:31
【问题描述】:

在链函数调用中传递参数的pythonic方法是什么?假设我有以下功能:

 def get_remainder(timeseries,freq, model='additive', item='residue'):

      if item == 'residue':
          return decompose(timeseries, freq=freq, model=model).residue
      elif item == 'trend':
          return decompose(timeseries, freq=freq, model=model).trend

对于这个问题,decompose 函数存在并且并不重要。它将 multiplicativeadditive 作为模型作为字符串。如您所见,get_remainder 返回残差或趋势。所以总而言之,我们在这里有四个选择。我们可以

  • model='additive', item='trend'
  • model='additive', item='residue'
  • model='multiplicative' 等。

问题是get_remainder 是链中的最后一个调用:

def func1(data, params):
    # does something to data, maybe shape is different, maybe some elements deleted etc. 
    return func2(data, params)

def func2(data, params):
    # does something to data 
    return func3(data, params)

def func3(data, params):
    # does something to data 
    remainder = get_remainder(timeseries,freq, model=params['model'], item=params['residue']):
    # does something to remainder. 
    returns remainder <> data 

其中&lt;&gt; 表示某种涉及余数和数据的操作。我希望能够从第一个函数func1 中获取所有四种类型,所以我一直在params 参数中传递modelitem

但这对我来说似乎很奇怪/不符合pythonic。中间函数都没有直接使用modelitem(尽管params 可能包含其他参数),它们只是携带它,所以最后一个函数可以使用它。

有什么更好的方法来做到这一点?

【问题讨论】:

  • 你可以创建一个对象,并让model/``item` 成为实例成员
  • 原来的get_remainder 可能看起来像这样一个班轮:return getattr(decompose(...), item)
  • 只有func1func2 的结果总是无趣吗?但据我所知,不少库使用**kwargs 来不断地传递参数。

标签: python python-3.x


【解决方案1】:

您正在寻找**kwargs(关键字参数)语法。现在您可以使用任意数量的关键字参数调用func1,这些参数将被收集到一个名为params 的字典中。当你调用另一个函数时,你可以使用字典解包语法**params解包params。所以func2(data, **{"model": "additive"})func2(data, model="additive") 相同。

如果函数签名中包含关键字参数,它将不会作为**params 的一部分被收集。对于函数def f(a=1, **kwargs),调用f(**{"a": 2}) 将使kwargs 留空。

def func1(data, **params):
    # does something to data, maybe shape is different, maybe some elements deleted etc. 
    return func2(data, **params)

def func2(data, **params):
    # does something to data 
    return func3(data, **params)

def func3(data, **params):
    # does something to data 
    remainder = get_remainder(timeseries,freq, **params)

def get_remainder(timeseries,freq, model='additive', item='residue'):
    if item == 'residue':
        return decompose(timeseries, freq=freq, model=model).residue
    elif item == 'trend':
        return decompose(timeseries, freq=freq, model=model).trend

【讨论】:

  • 谢谢!我最近听说了 python 中的装饰器。这个问题可以使用装饰器解决吗?还是kwargs 是标准的解决方法?
  • kwargs 绝对是标准方式。我想不出使用装饰器的好方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-12
  • 1970-01-01
  • 2015-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多