0

我想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()

4

2 回答 2

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这当然只适用于不接受、仅关键字参数或的函数**kwargs,但您可以通过一些工作将其扩展为也适用于它们。(有关详细信息,请参阅co_kwonlyargcountco_flagsCO_VARARGSCO_VARKEYWORDS。)

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

于 2018-05-14T03:27:03.530 回答
1

*args构造将为您提供作为列表的参数:

>>> 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().

于 2018-05-14T03:03:11.747 回答