如何将函数映射到所有参数值,作为列表?但在函数定义中有明确的参数名称

时间:2018-05-14 03:00:13

标签: python function arguments named positional-parameter

我想在函数定义中使用显式参数名ff(a,b,c)定义一个函数,但我也想在所有参数上映射一个函数来获取一个列表:

ff(a,b,c):
    return list(map(myfunc,[a,b,c]))

但是,我不想在函数中明确地将参数名称写为a,b,c。我想这样做

ff(a,b,c):
    return list(map(myfunc,getArgValueList()))

getArgValueList()将按顺序检索参数值并形成列表。这该怎么做?是否有内置函数,如getArgValueList()

2 个答案:

答案 0 :(得分:2)

如果没有丑陋的黑客,你想要做的事情是不可能的。您可以使用*args获取一系列可用作args的参数值:

def ff(*args):
    return list(map(myfunc, args))

...或者您使用三个显式参数并按名称使用它们:

def ff(a, b, c):
    return list(map(myfunc, (a, b, c)))

......但它是一个或另一个,而不是两者。

当然,如果您愿意,可以自己将这些值放入序列中:

def ff(a, b, c):
    args = a, b, c
    return list(map(myfunc, args))

......但我不确定是什么让你买的。

如果您真的想知道如何编写getArgValueList函数,我将解释如何执行此操作。但是,如果您希望使代码更具可读性,更高效,更具惯用性,更易于理解,更简洁,或几乎任何其他内容,那么它将产生完全相反的效果。我可以想象做这样的事情的唯一原因是你必须动态生成函数或者某些东西 - 即便如此,我也想不出你不能只使用*args的原因。但是,如果你坚持:

def getArgValueList():
    frame = inspect.currentframe().f_back
    code = frame.f_code
    vars = code.co_varnames[:code.co_argcount]
    return [frame.f_locals[var] for var in vars]

如果你想知道它是如何工作的,大部分内容都在inspect模块文档中:

  • currentframe()获取当前帧 - getArgValueList
  • 的帧
  • f_back获取父框架 - 任何调用getArgValueList的人的框架。
  • f_code获取从调用getArgValueList的任何人的函数体编译的代码对象。
  • co_varnames是该实体中所有局部变量的列表,从参数开始。
  • co_argcount是显式位置或关键字参数的计数。
  • f_locals是一个带有框架locals()环境副本的字典。

这当然仅适用于不使用*args,仅关键字的args或**kwargs的函数,但您可以通过一些工作扩展它以适用于它们。 (有关详细信息,请参阅co_kwonlyargcountco_flagsCO_VARARGSCO_VARKEYWORDS。)

此外,这仅适用于CPython,而不适用于大多数其他解释器。并且它可能在未来的某个版本中破解,因为它非常公然地依赖于解释器的实现细节。

答案 1 :(得分:1)

*args construction会以列表的形式提供参数:

>>> def f(*args): return list(map(lambda x:x+1, args))
>>> f(1,2,3)
[2, 3, 4]

如果您使用f的签名,则必须使用inspect模块:

import inspect

def f(a, b,c):
    f_locals = locals()
    values = [f_locals[name] for name in inspect.signature(f).parameters]
    return list(map(lambda x:x+1, values))

inspect.signature(f).parameters以正确的顺序为您提供参数列表。值在locals()