如何找到Python函数的参数个数?

How can I find the number of arguments of a Python function?

如何找到python函数的参数个数?我需要知道它有多少个正常参数,有多少个命名参数。

例子:

1
2
def someMethod(self, arg1, kwarg1=None):
    pass

此方法有2个参数和1个命名参数。


1
2
import inspect
inspect.getargspec(someMethod)

参见检查模块


先前接受的答案已从Python 3.0起被否决。现在,您应该选择替代它的Signature类,而不是使用inspect.getargspec

通过Signature函数很容易为函数创建签名:

1
2
3
4
5
6
from inspect import signature

def someMethod(self, arg1, kwarg1=None):
    pass

sig = signature(someMethod)

现在,您可以通过EDOCX1[4]快速查看其参数:

1
str(sig)  # returns: '(self, arg1, kwarg1=None)'

或者,您也可以通过sig.parameters获得属性名到参数对象的映射。

1
2
params = sig.parameters
print(params['kwarg1']) # prints: kwarg1=20

此外,可以在sig.parameters上调用len,以查看此函数需要的参数数量:

1
print(len(params))  # 3

params映射中的每个条目实际上都是一个Parameter对象,具有更多的属性,使您的生活更轻松。例如,抓取参数并查看其默认值现在可以很容易地用以下方法执行:

1
2
kwarg1 = params['kwarg1']
kwarg1.default # returns: None

对于parameters中包含的其他对象也是如此。

至于python 2.x用户,虽然inspect.getargspec没有被否决,但语言很快就会是:—)。Signature类在2.x系列中不可用,不会。所以你仍然需要和inspect.getargspec合作。

至于在python 2和3之间的转换,如果在python 2中有依赖于getargspec接口的代码,在3中切换到Signature太困难,那么使用inspect.getfullargspec是很有价值的选择。它提供了一个与getargspec类似的接口(单个可调用参数),以便获取函数的参数,同时处理getargspec没有:

1
2
3
4
5
6
from inspect import getfullargspec

def someMethod(self, arg1, kwarg1=None):
    pass

args = getfullargspec(someMethod)

getargspec一样,getfullargspec返回包含参数的NamedTuple

1
2
print(args)
FullArgSpec(args=['self', 'arg1', 'kwarg1'], varargs=None, varkw=None, defaults=(None,), kwonlyargs=[], kwonlydefaults=None, annotations={})


1
someMethod.func_code.co_argcount

或者,如果当前函数名未确定:

1
2
3
import sys

sys._getframe().func_code.co_argcount


检查.getargspec()

Get the names and default values of a function’s arguments. A tuple of four things is returned: (args, varargs, varkw, defaults). args is a list of the argument names (it may contain nested lists). varargs and varkw are the names of the * and ** arguments or None. defaults is a tuple of default argument values or None if there are no default arguments; if this tuple has n elements, they correspond to the last n elements listed in args.

Changed in version 2.6: Returns a named tuple ArgSpec(args, varargs, keywords, defaults).

请参见can-you-list-the-keyword-arguments-a-python-function-receives。


除此之外,我还看到大多数时候help()函数确实有帮助

例如,它给出了它所采用的参数的所有细节。

1
help(<method>)

给出以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
method(self, **kwargs) method of apiclient.discovery.Resource instance
Retrieves a report which is a collection of properties / statistics for a specific customer.

Args:
  date: string, Represents the date in yyyy-mm-dd format for which the data is to be fetched. (required)
  pageToken: string, Token to specify next page.
  parameters: string, Represents the application name, parameter name pairs to fetch in csv as app_name1:param_name1, app_name2:param_name2.

Returns:
  An object of the form:

    { # JSON template for a collection of usage reports.
   "nextPageToken":"A String", # Token for retrieving the next page
   "kind":"admin#reports#usageReports", # Th


对于希望在python 2和python 3.6+之间以可移植的方式进行此操作的人来说,这是个好消息:使用inpsect.getfullargspec( )方法。它在python 2.x和3.6中都能工作+

正如Jim Fasarakis Hilliard和其他人所指出的,过去是这样的:1。在python 2.x中:使用inspect.getargspec( )2。在python 3.x中:使用签名,因为getargspec( )getfullargspec( )被弃用。

但是,从Python3.6开始(按流行需求?),情况有所好转:

从python 3文档页面:

inspect.getfullargspec(func)

Changed in version 3.6: This method was previously documented as deprecated in favour of signature() in Python 3.5, but that decision has been reversed in order to restore a clearly supported standard interface for single-source Python 2/3 code migrating away from the legacy getargspec() API.


检查.getargspec()以满足您的需要

1
2
3
4
5
from inspect import getargspec

def func(a, b):
    pass
print len(getargspec(func).args)


正如其他答案所表明的,只要被查询的对象实际上是一个函数,getargspec就可以很好地工作。它不适用于诸如openlen等内置函数,并且在这种情况下会引发异常:

1
TypeError: <built-in function open> is not a Python function

下面的函数(受这个答案的启发)演示了一种变通方法。返回f期望的参数个数:

1
2
3
4
5
6
7
8
9
from inspect import isfunction, getargspec
def num_args(f):
  if isfunction(f):
    return len(getargspec(f).args)
  else:
    spec = f.__doc__.split('
'
)[0]
    args = spec[spec.find('(')+1:spec.find(')')]
    return args.count(',')+1 if args else 0

其思想是从__doc__字符串中解析函数规范。显然,这依赖于所述字符串的格式,因此很难实现健壮性!