获取传递给函数的参数的列表/元组/字典?

Phi*_*ham 62 python arguments function

鉴于以下功能:

def foo(a, b, c):
    pass
Run Code Online (Sandbox Code Playgroud)

如何获得传入的参数的list/tuple/dict/etc,而不必自己构建结构

具体来说,我正在寻找Python的JavaScript arguments关键字版本或PHP的func_get_args()方法.

想要的是使用*args或的解决方案**kwargs; 我需要在函数定义中指定参数名称(以确保它们被传入),但在函数中我希望在list-或dict-style结构中使用它们.

Pär*_*der 80

您可以使用locals()在函数中获取局部变量的dict,如下所示:

def foo(a, b, c):
    print locals()

>>> foo(1, 2, 3)
{'a': 1, 'c': 3, 'b': 2}
Run Code Online (Sandbox Code Playgroud)

但是,这有点hackish,因为locals()返回本地范围内的所有变量,而不仅仅是传递给函数的参数,所以如果你不在函数的最顶层调用它,结果可能包含的信息比你想要的多:

def foo(a, b, c):
    x = 4
    y = 5
    print locals()

>>> foo(1, 2, 3)
{'y': 5, 'x': 4, 'c': 3, 'b': 2, 'a': 1}
Run Code Online (Sandbox Code Playgroud)

我宁愿在你的函数顶部构建一个dict或变量列表,如其他答案所示.它更明确,并以更清晰的方式传达代码的意图,恕我直言.

  • 谢谢.对于任何想要使用此方法的人,请记住在函数定义之后应直接使用`locals()`,否则它将包含函数中定义的所有变量. (5认同)
  • 同样有趣的是,如果您在方法中使用 locals(),则 dict 中的键之一是“self”。因此,请确保您对此进行更正/说明。 (3认同)
  • 有趣的是,`locals()`返回局部变量的快照,而不是指向某个内置字典的指针.因此,如果稍后定义变量或在函数内更改参数,则指定的"locals()"将不会更改.这就是你想要的.(我是Python.) (2认同)

kro*_*ger 7

您可以使用inspect模块:

def foo(x):
    return x

inspect.getargspec(foo)
Out[23]: ArgSpec(args=['x'], varargs=None, keywords=None, defaults=None)
Run Code Online (Sandbox Code Playgroud)

这是一个重复的这个这个.

  • 你不能在一个功能内做到这一点,对吗? (3认同)

Xav*_*lle 5

如果参数不符合预期,我将使用*argsor**kwargs并抛出异常

如果你想得到与 python 检查的错误相同的错误,你可以做类似的事情

def check_arguments(function_name,args,arg_names):
    missing_count = len(arg_names) - len(args)
    if missing_count > 0:
        if missing_count == 1:
            raise TypeError(function_name+"() missing 1 required positionnal argument: "+repr(arg_names[-1]))
        else:
            raise TypeError(function_name+"() missing "+str(missing_count)+" required positionnal argument: "+", ".join([repr(name) for name in arg_names][-missing_count:-1])+ " and "+repr(arg_names[-1]))
Run Code Online (Sandbox Code Playgroud)

与类似的东西一起使用

def f(*args):
    check_arguments("f",args,["a","b","c"])
    #whatever you want
    ...
Run Code Online (Sandbox Code Playgroud)

  • 这将需要在方法主体内进行大量测试,而将参数定义为函数的一部分会在没有任何额外测试的情况下引发类似的错误。 (2认同)

Eso*_*ack 5

这是您可以调用以获取当前函数的 kwargs 的函数。或者,如果您想直接在您自己的函数中使用这些行而不是调用,get_kwargs()只需删除.f_back

import inspect


def get_kwargs():
    frame = inspect.currentframe().f_back
    keys, _, _, values = inspect.getargvalues(frame)
    kwargs = {}
    for key in keys:
        if key != 'self':
            kwargs[key] = values[key]
    return kwargs


def test(x, y=100):
    z = 7
    print(get_kwargs())


test(5, 6)
# Output: {'x': 5, 'y': 6}
test(5)
# Output: {'x': 5, 'y': 100}
Run Code Online (Sandbox Code Playgroud)