假设函数a_method的定义如下

def a_method(arg1, arg2):
    pass

从a_method本身开始,我怎么能得到参数名-例如,作为字符串的元组,如("arg1", "arg2")?


当前回答

我在谷歌上搜索如何打印函数名,并为赋值提供参数,我必须创建一个装饰器来打印它们,我使用了这个:

def print_func_name_and_args(func):
    
    def wrapper(*args, **kwargs):
    print(f"Function name: '{func.__name__}' supplied args: '{args}'")
    func(args[0], args[1], args[2])
    return wrapper


@print_func_name_and_args
def my_function(n1, n2, n3):
    print(n1 * n2 * n3)
    
my_function(1, 2, 3)

#Function name: 'my_function' supplied args: '(1, 2, 3)'

其他回答

在CPython中,参数的数量是

a_method.func_code.co_argcount

他们的名字在开头

a_method.func_code.co_varnames

这些是CPython的实现细节,所以这可能不适用于Python的其他实现,比如IronPython和Jython。

承认“传递”参数的一种可移植方法是使用func(*args, **kwargs)签名来定义函数。这在matplotlib中被大量使用,其中外层API层将大量关键字参数传递给底层API。

下面是另一种不使用任何模块获得函数参数的方法。

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))

输出:

(('a', 'b'), {'c': 'hello', 'd': 'world'})

看一下inspect模块——它将为你检查各种代码对象属性。

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

其他结果是*args和**kwargs变量的名称,以及提供的默认值。ie。

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

注意,在Python的某些实现中,一些可调用对象可能不是可内省的。例如,在CPython中,一些用C定义的内置函数不提供关于其参数的元数据。因此,如果在内置函数上使用inspect.getfullargspec(),将会得到一个ValueError。

从Python 3.3开始,你可以使用inspect.signature()来查看可调用对象的调用签名:

>>> inspect.signature(foo)
<Signature (a, b, c=4, *arglist, **keywords)>

Python 3.5 +:

DeprecationWarning: inspect.getargspec()自Python 3.0起已弃用,请使用inspect.signature()或inspect.getfullargspec()

所以之前:

func_args = inspect.getargspec(function).args

Now:

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

测试:

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

假设函数function接受参数arg,它的值为True,否则为False。

来自Python控制台的示例:

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

Python 3的版本是:

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

该方法返回一个包含args和kwargs的字典。