我想在函数定义中使用显式参数名称
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()
这样的内置函数?
如果没有丑陋的黑客手段,你想要做的事情是不可能的。您可以采用
*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_kwonlyargcount
、co_flags
、CO_VARARGS
和 CO_VARKEYWORDS
。)
此外,这只适用于 CPython,不适用于大多数其他解释器。它可能会在未来的版本中出现问题,因为它非常明显地依赖于解释器的实现细节。
*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()
。