假设函数a_method的定义如下

def a_method(arg1, arg2):
    pass

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


当前回答

看一下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)>

其他回答

在CPython中,参数的数量是

a_method.func_code.co_argcount

他们的名字在开头

a_method.func_code.co_varnames

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

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

现在dir()和vars()呢?

似乎做什么是被要求超级简单…

必须从函数范围内调用。

但要注意,它将返回所有局部变量,所以如果需要,请确保在函数的最开始执行。

还要注意,正如评论中指出的那样,这不允许从作用域之外执行此操作。所以不完全是OP的情况,但仍然符合题目。这就是我的回答。

操作一些函数的参数名称的最简单方法:

parameters_list = list(inspect.signature(self.YOUR_FUNCTION).parameters))

结果:

['YOUR_FUNCTION_parameter_name_0', 'YOUR_FUNCTION_parameter_name_1', ...]

这样做会更容易,因为你得到了具体的一个:

parameters_list = list(inspect.signature(self.YOUR_FUNCTION).parameters)[0]

结果:

'YOUR_FUNCTION_parameter_name_0'

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

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

布莱恩的回答更新如下:

如果Python 3中的函数只有关键字参数,那么你需要使用inspect.getfullargspec:

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

收益率:

FullArgSpec(args=['a', 'b'], varargs=None, varkw=None, defaults=(10,), kwonlyargs=['c', 'd'], kwonlydefaults={'c': 20, 'd': 30}, annotations={})