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

时间:2009-05-11 12:45:16

标签: python function

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

示例:

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

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

12 个答案:

答案 0 :(得分:116)

import inspect
inspect.getargspec(someMethod)

请参阅the inspect module

答案 1 :(得分:81)

Python 3.0起,之前接受的答案为deprecated。您现在应该选择取代它的inspect.getargspec类,而不是使用Signature

通过signature function

可以轻松地为该功能创建签名
from inspect import signature

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

sig = signature(someMethod)

现在,您可以通过str快速查看其参数:

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

或者您还可以通过sig.parameters获取属性名称到参数对象的映射。

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

此外,您可以在len上调用sig.parameters以查看此功能所需的参数数量:

print(len(params))  # 3

params映射中的每个条目实际上都是Parameter object,其中包含更多属性,让您的生活更轻松。例如,现在可以使用以下方法轻松执行抓取参数并查看其默认值:

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

类似于parameters中包含的其他对象。

对于Python 2.x用户,虽然{@ 1}} 不赞成,但语言很快就会:-)。 inspect.getargspec系列中Signature课程不可用,但不会有。{1}}课程。因此,您仍需要使用inspect.getargspec

至于在Python 2和3之间进行转换,如果您的代码依赖于Python 2中的2.x接口并且切换到getargspec中的signature太难了, >您确实拥有使用inspect.getfullargspec的宝贵选项。它提供了与3(一个可调用参数)类似的接口,以便获取函数的参数,同时还处理getargspec不会出现的其他一些情况:

getargspec

from inspect import getfullargspec def someMethod(self, arg1, kwarg1=None): pass args = getfullargspec(someMethod) 一样,getargspec会返回包含参数的getfullargspec

NamedTuple

答案 2 :(得分:28)

someMethod.func_code.co_argcount

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

import sys

sys._getframe().func_code.co_argcount

答案 3 :(得分:16)

inspect.getargspec()

  

获取函数参数的名称和默认值。返回四个元组的元组:(args,varargs,varkw,defaults)。 args是参数名称的列表(它可能包含嵌套列表)。 varargs和varkw是*和**参数的名称或None。 defaults是默认参数值的元组,如果没有默认参数,则为None;如果这个元组有n个元素,它们对应于args中列出的最后n个元素。

     

在2.6版中更改:返回一个名为元组的ArgSpec(args,varargs,keywords,defaults)。

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

答案 4 :(得分:4)

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

例如,它提供了所需参数的所有细节。

help(<method>)

给出以下

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

答案 5 :(得分:4)

func.__code__.co_argcount为您提供 参数的数量 之前 *args

func.__kwdefaults__为您提供关键字参数的字典 之后 *args

func.__code__.co_kwonlyargcount等于len(func.__kwdefaults__)

func.__defaults__为您提供可选参数的值,该值出现在之前 *args

这是简单的例子:

the illustration

>>> def a(b, c, d, e, f=1, g=3, h=None, *i, j=2, k=3, **L):
    pass

>>> a.__code__.co_argcount
7
>>> a.__defaults__
(1, 3, None)
>>> len(a.__defaults__)
3
>>> 
>>> 
>>> a.__kwdefaults__
{'j': 2, 'k': 3}
>>> len(a.__kwdefaults__)
2
>>> a.__code__.co_kwonlyargcount
2

答案 6 :(得分:3)

对于希望以可移植的方式在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( )

但是,从Python 3.6开始(由于流行的需求?),情况已经变得更好:

从Python 3 documentation page

  

inspect.getfullargspec(func)

     

在版本3.6中已更改:以前在Python 3.5中记录此方法已弃用,而推荐使用signature(),但为了恢复明显支持的标准接口而撤销了该决定。单源Python 2/3代码从旧版getargspec() API迁移而来。

答案 7 :(得分:2)

inspect.getargspec()满足您的需求

from inspect import getargspec

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

答案 8 :(得分:1)

正如其他答案所暗示的那样,只要被查询的内容实际上是一个函数,getargspec就可以正常工作。它不适用于内置函数,例如openlen等,并会在这种情况下抛出异常:

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

以下功能(受this answer启发)演示了一种解决方法。它返回f预期的args数:

from inspect import isfunction, getargspec
def num_args(f):
  if isfunction(f):
    return len(getargspec(f).args)
  else:
    spec = f.__doc__.split('\n')[0]
    args = spec[spec.find('(')+1:spec.find(')')]
    return args.count(',')+1 if args else 0

我们的想法是从__doc__字符串中解析函数规范。显然这取决于所述字符串的格式,所以几乎不健壮!

答案 9 :(得分:0)

在:

import inspect 

class X:
    def xyz(self, a, b, c): 
        return 

print(len(inspect.getfullargspec(X.xyz).args))

出局:

4


注意:如果xyz不在X类之内,并且没有“自我”,而只有“ a,b,c”,那么它将打印3。

对于低于3.5的python,您可能希望在上面的代码中将inspect.getfullargspec替换为inspect.getargspec

答案 10 :(得分:0)

Dimitris Fasarakis Hilliard 接受的答案建议以字符串格式获取参数,但我认为在解析此字符串时可能会出错,因此我直接使用检查模块创建了一个参数列表

import inspect
def my_function(a,b,c):
    #some code
    pass

result=list(inspect.signature(my_function).parameters.keys())
print(result)
['a','b','c']

答案 11 :(得分:0)

假设您可能正在处理基于类的 method 或简单的 function,您可以执行以下操作。

如果输入是类方法(因此包括 self),这将自动减去一个输入。

import types
def get_arg_count(fn):
    extra_method_input_count=1 if isinstance(fn, types.MethodType) else 0
    return fn.__code__.co_argcount-extra_method_input_count

然后你可以根据需要申请函数或方法:

def fn1(a, b, c):
    return None

class cl1:
    def fn2(self, a, b, c):
        return None

print(get_arg_count(fn1)) #=> 3
print(get_arg_count(cl1().fn2)) #=> 3