如何找到python函数的参数个数?我需要知道它有多少个正常参数,有多少个命名参数。
例子:
1
2def someMethod(self, arg1, kwarg1=None):
pass
此方法有2个参数和1个命名参数。
这个问题是完全有理由的;如果它不是(因为您总是可以读取源代码),那么对于inspect标准库模块就没有任何理由了。
许多语言至少实现一个不合理的特性。inspect模块有很多其他特性,所以不公平地说,如果其中一个特定的功能是不合理的。此外,很容易看出这个特性是如何使用得不好的。(请参阅stackoverflow.com/questions/741950)。也就是说,它是一个有用的特性,特别是对于编写装饰器和其他操作函数的函数来说。
1
2import inspect
inspect.getargspec(someMethod)
参见检查模块
通常是您想要的,但这不适用于内置函数。要知道为内置函数获取这些信息,唯一的方法是解析它们的文档字符串,该字符串虽然简单但可行。
在python 3:docs.python.org/3/library/inspect.html inspect.getargspec中不推荐使用这种方法。
有没有在python 3中不推荐的解决方案?
如果您遵循链接,您将看到它建议使用inspect.signature-docs.python.org/3/library/inspect.html inspect.signature。
我在这里发布了另一种不解析docstring的内置函数方法:stackoverflow.com/questions/48567935/…
先前接受的答案已从Python 3.0起被否决。现在,您应该选择替代它的Signature类,而不是使用inspect.getargspec。
通过Signature函数很容易为函数创建签名:
1
2
3
4
5
6from inspect import signature
def someMethod(self, arg1, kwarg1=None):
pass
sig = signature(someMethod)
。
现在,您可以通过EDOCX1[4]快速查看其参数:
1str(sig) # returns: '(self, arg1, kwarg1=None)'
。
或者,您也可以通过sig.parameters获得属性名到参数对象的映射。
1
2params = sig.parameters
print(params['kwarg1']) # prints: kwarg1=20
此外,可以在sig.parameters上调用len,以查看此函数需要的参数数量:
1print(len(params)) # 3
。
params映射中的每个条目实际上都是一个Parameter对象,具有更多的属性,使您的生活更轻松。例如,抓取参数并查看其默认值现在可以很容易地用以下方法执行:
1
2kwarg1 = 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
6from inspect import getfullargspec
def someMethod(self, arg1, kwarg1=None):
pass
args = getfullargspec(someMethod)
。
与getargspec一样,getfullargspec返回包含参数的NamedTuple。
1
2print(args)
FullArgSpec(args=['self', 'arg1', 'kwarg1'], varargs=None, varkw=None, defaults=(None,), kwonlyargs=[], kwonlydefaults=None, annotations={})
号
不客气@Georgsch&246;lly。我很惊讶,像这样一个流行的问题提供了一些解决方案,要么被否决,要么是不怀好意(偷看co_argcount属性)。
在python 2.x中没有实现getfullargspec,需要使用getargspec。
getargspec不适用于内置功能:getargspec(open)给TypeError: is not a Python function一些想法见这个答案…
在上一个例子中,当你做print(args)时,你没有得到defaults=(None,),你得到defaults=None。
1someMethod.func_code.co_argcount
号
或者,如果当前函数名未确定:
1
2
3import sys
sys._getframe().func_code.co_argcount
@Elyase,只需做:dir(someMethod)->'func_code';进一步:dir(someMethod.func_code)->'co_argcount';您可以使用内置的dir()来确定对象的可用方法。
@Elyase我也很勇敢,所以我找到了docs.python.org/2/library/inspect.html类型和成员
支持python 3:six.get_function_code(someMethod).co_argcount。
@Noisecapella不需要第三方模块,只需执行some_method.__code__.co_argcount
一般来说,您不应该窥视函数对象内部来查看这些内容。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()函数确实有帮助
例如,它给出了它所采用的参数的所有细节。
1help()
。
给出以下内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14method(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
对人们来说,最好是对一篇文章的错误发表评论,而不是仅仅点击减号按钮。
help函数只显示docstring所说的内容。您是否测试过它是否适用于问题中的函数定义?
@你测试过吗?因为它确实有效。help()不仅输出docstring——即使在未记录的代码上,它仍然输出argspec,并告诉您在哪里定义了代码。发布原始问题的人不清楚他们是否需要一个对机器或人类友好的答案。如果只需要对人类友好,那么help()就完全足够了。
@根本不是战争的艺术,因为现在你必须分析help()的返回,并试图找到args和kwargs。
对于希望在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
5from inspect import getargspec
def func(a, b):
pass
print len(getargspec(func).args)
号
欢迎使用堆栈溢出!请不要只用源代码回答。尝试提供关于解决方案如何工作的很好的描述。看:我怎么写一个好答案?.谢谢。
正如其他答案所表明的,只要被查询的对象实际上是一个函数,getargspec就可以很好地工作。它不适用于诸如open和len等内置函数,并且在这种情况下会引发异常:
1TypeError: is not a Python function
号
下面的函数(受这个答案的启发)演示了一种变通方法。返回f期望的参数个数:
1
2
3
4
5
6
7
8
9from 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__字符串中解析函数规范。显然,这依赖于所述字符串的格式,因此很难实现健壮性!