How to get method parameter names?

前端 未结 15 2150
眼角桃花
眼角桃花 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:44

    The Python 3 version is:

    def _get_args_dict(fn, args, kwargs):
        args_names = fn.__code__.co_varnames[:fn.__code__.co_argcount]
        return {**dict(zip(args_names, args)), **kwargs}
    

    The method returns a dictionary containing both args and kwargs.

    0 讨论(0)
  • 2020-11-22 09:45

    Here is another way to get the function parameters without using any module.

    def get_parameters(func):
        keys = func.__code__.co_varnames[:func.__code__.co_argcount][::-1]
        sorter = {j: i for i, j in enumerate(keys[::-1])} 
        values = func.__defaults__[::-1]
        kwargs = {i: j for i, j in zip(keys, values)}
        sorted_args = tuple(
            sorted([i for i in keys if i not in kwargs], key=sorter.get)
        )
        sorted_kwargs = {
            i: kwargs[i] for i in sorted(kwargs.keys(), key=sorter.get)
        }   
        return sorted_args, sorted_kwargs
    
    
    def f(a, b, c="hello", d="world"): var = a
        
    
    print(get_parameters(f))
    

    Output:

    (('a', 'b'), {'c': 'hello', 'd': 'world'})
    
    0 讨论(0)
  • 2020-11-22 09:49

    Here is something I think will work for what you want, using a decorator.

    class LogWrappedFunction(object):
        def __init__(self, function):
            self.function = function
    
        def logAndCall(self, *arguments, **namedArguments):
            print "Calling %s with arguments %s and named arguments %s" %\
                          (self.function.func_name, arguments, namedArguments)
            self.function.__call__(*arguments, **namedArguments)
    
    def logwrap(function):
        return LogWrappedFunction(function).logAndCall
    
    @logwrap
    def doSomething(spam, eggs, foo, bar):
        print "Doing something totally awesome with %s and %s." % (spam, eggs)
    
    
    doSomething("beans","rice", foo="wiggity", bar="wack")
    

    Run it, it will yield the following output:

    C:\scripts>python decoratorExample.py
    Calling doSomething with arguments ('beans', 'rice') and named arguments {'foo':
     'wiggity', 'bar': 'wack'}
    Doing something totally awesome with beans and rice.
    
    0 讨论(0)
  • 2020-11-22 09:49

    In Python 3.+ with the Signature object at hand, an easy way to get a mapping between argument names to values, is using the Signature's bind() method!

    For example, here is a decorator for printing a map like that:

    import inspect
    
    def decorator(f):
        def wrapper(*args, **kwargs):
            bound_args = inspect.signature(f).bind(*args, **kwargs)
            bound_args.apply_defaults()
            print(dict(bound_args.arguments))
    
            return f(*args, **kwargs)
    
        return wrapper
    
    @decorator
    def foo(x, y, param_with_default="bars", **kwargs):
        pass
    
    foo(1, 2, extra="baz")
    # This will print: {'kwargs': {'extra': 'baz'}, 'param_with_default': 'bars', 'y': 2, 'x': 1}
    
    0 讨论(0)
  • 2020-11-22 09:50

    I think what you're looking for is the locals method -

    
    In [6]: def test(a, b):print locals()
       ...: 
    
    In [7]: test(1,2)              
    {'a': 1, 'b': 2}
    
    0 讨论(0)
  • 2020-11-22 09:53

    Python 3.5+:

    DeprecationWarning: inspect.getargspec() is deprecated, use inspect.signature() instead

    So previously:

    func_args = inspect.getargspec(function).args
    

    Now:

    func_args = list(inspect.signature(function).parameters.keys())
    

    To test:

    'arg' in list(inspect.signature(function).parameters.keys())
    

    Given that we have function 'function' which takes argument 'arg', this will evaluate as True, otherwise as False.

    Example from the Python console:

    Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 07:18:10) [MSC v.1900 32 bit (Intel)] on win32
    >>> import inspect
    >>> 'iterable' in list(inspect.signature(sum).parameters.keys())
    True
    
    0 讨论(0)
提交回复
热议问题