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

时间:2010-03-26 08:30:55

标签: python function arguments

给出以下功能:

def foo(a, b, c):
    pass

如何获取传入的参数的列表/元组/字典/等,而不必自己构建结构

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

寻找的是使用*args**kwargs的解决方案;我需要在函数定义中指定参数名称(以确保它们被传入),但在函数中我希望在列表或字典样式结构中使用它们。

9 个答案:

答案 0 :(得分:71)

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

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

>>> foo(1, 2, 3)
{'a': 1, 'c': 3, 'b': 2}

然而,这有点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}

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

答案 1 :(得分:7)

您可以使用检查模块:

def foo(x):
    return x

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

这是thisthis的副本。

答案 2 :(得分:4)

如果参数不符合预期,我会使用*args**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]))

与某些人一起使用

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

答案 3 :(得分:4)

这里有一个函数,你可以调用它来获取当前函数的 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}

答案 4 :(得分:1)

您是否在标题中指定了参数?

为什么不直接在身体中使用相同的信息?

def foo(a, b, c):
   params = [a, b, c]

我错过了什么?

答案 5 :(得分:1)

您可以使用以下方法创建一个列表:

args = [a, b, c]

您可以使用以下方法轻松创建元组:

args = (a, b, c)

答案 6 :(得分:1)

使用装饰器的一个解决方案是here

答案 7 :(得分:1)

来自重复(较早的)问题https://stackoverflow.com/a/582206/1136458的接受答案:

    frame = inspect.currentframe()
    args, _, _, values = inspect.getargvalues(frame)

答案 8 :(得分:0)

class my_class():
        compulsory_default_kwargs = {'p':20,'q':30,'r':40}
        formal_args_names = ['var1','var2']
        def __init__(self,*args,**kwargs):
            for key , value in locals().items():
                if((key == 'args')):
                    if(len(args) == len(my_class.formal_args_names)):
                        for key_name , arg_value in zip(my_class.formal_args_names,args):
                            setattr(self,key_name,arg_value)
                    else:
                        raise Exception ('Error - Number of formal arguments passed mismatched required {} whereas passed {}'.format(len(my_class.formal_args_names),len(args)))

                elif((key == 'kwargs') & (len(kwargs)!=0)):
                    for kw_key , kw_value in kwargs.items():
                        if kw_key in my_class.compulsory_default_kwargs.keys():
                            setattr(self,kw_key,kw_value)
                        else:
                            raise Exception ('Invalid key-word argument passed {}'.format(kw_key))
                #elif((key!='self') & (key!='kwargs') ):
                   # setattr(self,key,value)
            for key , value in my_class.compulsory_default_kwargs.items():
                if key not in kwargs.keys():
                    setattr(self,key,value)


    this_value = 'Foo'    
    my_cl = my_class(3,this_value,p='B',r=10)
    my_cl.__dict__