How to get method parameter names?

前端 未结 15 2149
眼角桃花
眼角桃花 2020-11-22 09:14

Given the Python function:

def a_method(arg1, arg2):
    pass

How can I extract the number and names of the arguments. I.e., given that I h

相关标签:
15条回答
  • 2020-11-22 09:36

    Returns a list of argument names, takes care of partials and regular functions:

    def get_func_args(f):
        if hasattr(f, 'args'):
            return f.args
        else:
            return list(inspect.signature(f).parameters)
    
    0 讨论(0)
  • 2020-11-22 09:38

    Update for Brian's answer:

    If a function in Python 3 has keyword-only arguments, then you need to use inspect.getfullargspec:

    def yay(a, b=10, *, c=20, d=30):
        pass
    inspect.getfullargspec(yay)
    

    yields this:

    FullArgSpec(args=['a', 'b'], varargs=None, varkw=None, defaults=(10,), kwonlyargs=['c', 'd'], kwonlydefaults={'c': 20, 'd': 30}, annotations={})
    
    0 讨论(0)
  • 2020-11-22 09:40

    In a decorator method, you can list arguments of the original method in this way:

    import inspect, itertools 
    
    def my_decorator():
    
            def decorator(f):
    
                def wrapper(*args, **kwargs):
    
                    # if you want arguments names as a list:
                    args_name = inspect.getargspec(f)[0]
                    print(args_name)
    
                    # if you want names and values as a dictionary:
                    args_dict = dict(itertools.izip(args_name, args))
                    print(args_dict)
    
                    # if you want values as a list:
                    args_values = args_dict.values()
                    print(args_values)
    

    If the **kwargs are important for you, then it will be a bit complicated:

            def wrapper(*args, **kwargs):
    
                args_name = list(OrderedDict.fromkeys(inspect.getargspec(f)[0] + kwargs.keys()))
                args_dict = OrderedDict(list(itertools.izip(args_name, args)) + list(kwargs.iteritems()))
                args_values = args_dict.values()
    

    Example:

    @my_decorator()
    def my_function(x, y, z=3):
        pass
    
    
    my_function(1, y=2, z=3, w=0)
    # prints:
    # ['x', 'y', 'z', 'w']
    # {'y': 2, 'x': 1, 'z': 3, 'w': 0}
    # [1, 2, 3, 0]
    
    0 讨论(0)
  • 2020-11-22 09:40

    inspect.signature is very slow. Fastest way is

    def f(a, b=1, *args, c, d=1, **kwargs):
       pass
    
    f_code = f.__code__
    f_code.co_varnames[:f_code.co_argcount + f_code.co_kwonlyargcount]  # ('a', 'b', 'c', 'd')
    
    0 讨论(0)
  • 2020-11-22 09:44

    Take a look at the inspect module - this will do the inspection of the various code object properties for you.

    >>> inspect.getfullargspec(a_method)
    (['arg1', 'arg2'], None, None, None)
    

    The other results are the name of the *args and **kwargs variables, and the defaults provided. ie.

    >>> def foo(a, b, c=4, *arglist, **keywords): pass
    >>> inspect.getfullargspec(foo)
    (['a', 'b', 'c'], 'arglist', 'keywords', (4,))
    

    Note that some callables may not be introspectable in certain implementations of Python. For Example, in CPython, some built-in functions defined in C provide no metadata about their arguments. As a result, you will get a ValueError if you use inspect.getfullargspec() on a built-in function.

    Since Python 3.3, you can use inspect.signature() to see the call signature of a callable object:

    >>> inspect.signature(foo)
    <Signature (a, b, c=4, *arglist, **keywords)>
    
    0 讨论(0)
  • 2020-11-22 09:44

    In CPython, the number of arguments is

    a_method.func_code.co_argcount
    

    and their names are in the beginning of

    a_method.func_code.co_varnames
    

    These are implementation details of CPython, so this probably does not work in other implementations of Python, such as IronPython and Jython.

    One portable way to admit "pass-through" arguments is to define your function with the signature func(*args, **kwargs). This is used a lot in e.g. matplotlib, where the outer API layer passes lots of keyword arguments to the lower-level API.

    0 讨论(0)
提交回复
热议问题