Python関数の引数の数を調べるにはどうすればよいですか?


163

Python関数の引数の数を調べるにはどうすればよいですか?通常の引数の数と名前付き引数の数を知る必要があります。

例:

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

このメソッドには2つの引数と1つの名前付き引数があります。


43
質問は完全に保証されています。そうでない場合(いつでもソースを読み取ることができるため)、inspect標準ライブラリモジュールを正当化することはできません。
フロー

多くの言語が少なくとも1つの不当な機能を実装しています。inspectそれで一つの特定の機能であった場合、モジュール全体が不当されるだろうと言うことは不公平であるので、モジュールは、他の機能をたくさん持っています。さらに、この機能がどのようにうまく使用されないかは簡単にわかります。(stackoverflow.com/questions/741950を参照)。とはいえ、それは特にデコレータや関数を操作する他の関数を書くのに役立つ機能です。
user1612868 2014年

回答:


130

以前に受け入れられた回答は、の時点で廃止されましたPython 3.0。使用inspect.getargspecする代わりに、Signatureそれを置き換えるクラスを選択する必要があります。

関数のシグネチャの作成は、関数を介して簡単signatureです

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

さらに、あなたは呼び出すことができます lensig.parametersも、この機能が必要とする引数の数を確認します。

print(len(params))  # 3

の各エントリ paramsマッピングの実際には、Parameterオブジェクトをより簡単に使用できるようにする追加の属性を持っています。たとえば、パラメータを取得してデフォルト値を表示することは、次のように簡単に実行できます。

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

に含まれる残りのオブジェクトについても同様ですparameters


Python 2.xユーザーについてinspect.getargspec は、非推奨ではありませんが、言語はまもなく:-)になります。このSignatureクラスは、2.xシリーズでません。したがって、引き続きで作業する必要がありますinspect.getargspec

あなたはのインターフェイスに依存しているコードがある場合はPython 2と3の間の移行については、getargspecPythonの2とへの切り替えsignatureでは3難しすぎると、あなたは貴重なオプション持っています使用してのをinspect.getfullargspec。これは、getargspec関数の引数を取得するために(単一の呼び出し可能な引数)と同様のインターフェースを提供すると同時に、次のような追加のケースを処理getargspecします。

from inspect import getfullargspec

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

args = getfullargspec(someMethod)

同じようにgetargspecgetfullargspec返すNamedTuple引数が含まれています。

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

1
@GeorgSchölly、どういたしまして。このような人気のある質問が、推奨されないか、卑劣な(co_argcount属性を覗く)ソリューションを提供していたことに驚いた
Dimitris Fasarakis Hilliard

1
getfullargspecはPython 2.xに実装されていないため、使用する必要がありますgetargspec
Peter Gibson

getargspec組み込み関数では機能しません:getargspec(open)TypeError: <built-in function open> is not a Python function
Gives

あなたの最後の例では、あなたがそうprint(args)するとき、あなたはあなたを得るdefaults=(None,)ことができませんdefaults=None
Seanny123 2018

si装飾後に装飾された関数の元のパラメーター数を取得する方法があります。
Gulats

117
import inspect
inspect.getargspec(someMethod)

検査モジュールを見る


5
通常は何をしたいか、これは組み込み関数では機能しません。ビルトインのこの情報を取得する唯一の方法は、ドキュメント文字列を解析することです。
セリン

5
これはPython 3で非推奨になりました:docs.python.org/3/library/inspect.html#inspect.getargspec
noisecapella

Python 3で廃止されないソリューションはありますか?
hlin117 2016年

1
リンクをたどると、使用することをお勧めします inspect.signature -docs.python.org
3

ここでdocstringを解析せずに組み込み関数の別の可能なアプローチを投稿しました: stackoverflow.com/questions/48567935/...
HelloWorldの

31
someMethod.func_code.co_argcount

または、現在の関数名が不明の場合:

import sys

sys._getframe().func_code.co_argcount

4
@elyase、ただ実行:dir(someMethod)-> 'func_code'; さらに進む:dir(someMethod.func_code)-> 'co_argcount'; 組み込みを使用してdir()、オブジェクトの使用可能なメソッドを判別できます。

@elyase私も好奇心旺盛だったので、このdocs.python.org/2/library/inspect.html#types-and-members
rodripfを

Python 3をサポートするには:six.get_function_code(someMethod).co_argcount
noisecapella 2016

8
@noisecapella簡単に実行できる場合、サードパーティのモジュールは不要some_method.__code__.co_argcount
vallentin 2016年

1
一般に、これらのことを確認するために関数オブジェクトを覗いてはいけませんco_argcountコードオブジェクトの評価中に内部的に使用されます。私が言おうとしていることは、これらの属性が1つのリリースから別のリリースに変更されないという保証はありません。
Dimitris Fasarakis Hilliard

16

inspect.getargspec()

関数の引数の名前とデフォルト値を取得します。4つの要素のタプルが返されます:(args、varargs、varkw、defaults)。argsは引数名のリストです(ネストされたリストが含まれる場合があります)。varargsおよびvarkwは、*および**引数の名前、またはNoneです。defaultsはデフォルトの引数値のタプルです。デフォルトの引数がない場合はNoneです。このタプルにn個の要素がある場合、それらはargsにリストされている最後のn個の要素に対応します。

バージョン2.6で変更:名前付きタプルArgSpec(args、varargs、キーワード、デフォルト)を返します。

can-you-list-the-keyword-arguments-a-python-function-receivesを参照してください。


5

上記に加えて、たいていの場合、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

マイナスボタンをクリックするだけではなく、投稿のどこが悪いのかについてコメントを残す方がよいでしょう。
Venu Murthy

2
help関数は、docstringが言うことだけを示します。問題の関数定義で機能するかどうかもテストしましたか?
0xc0de 2014年

@ 0xc0de-テストしましたか?実際に機能するからです。help()ドキュメント文字列だけでなく、ドキュメント化されていないコードでも、argspecが出力され、コードが定義された場所が示されます。元の質問を投稿した人は、機械にやさしい答えが必要かどうか明確ではありませんでした。人間にやさしいだけであればhelp()十分です。
ArtOfWarfare 2016年

@ArtOfWarfareすべてで、など今、あなたはどんな解析しなければならないhelp()リターンをし、試してみて、見つけるargskwargs
バレンティン2016年

5

Python 2とPython 3.6+の間でこれを移植可能な方法で実行したい人には朗報です。 inspect.getfullargspec()。メソッドを。Python 2.xと3.6+の両方で動作します

ジムFasarakisヒリアードと他の人が指摘したように、それはこのようにするために使用:
1でのPython 2.xの:使用inspect.getargspec()
2.でのPython 3.xの:使用の署名を、とgetargspec()し、getfullargspec()非推奨ました。

しかし、Python 3.6を開始して(大衆の需要によりますか?)、状況はより良い方向に変化しました。

Python 3 ドキュメントページから

inspect.getfullargspec(func)

バージョン3.6で変更:このメソッドは以前signature()はPython 3.5 で非推奨として文書化されていましたが、レガシーgetargspec()API から移行するシングルソースのPython 2/3コードの明確にサポートされている標準インターフェースを復元するために、この決定は取り消されました。


3

あなたのニーズを満たすためにinspect.getargspec()

from inspect import getargspec

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

1
Stack Overflowへようこそ!ソースコードだけで答えないでください。ソリューションがどのように機能するかについて、わかりやすい説明を提供してください。参照:良い回答を書くにはどうすればよいですか?。おかげで
sɐunıɔןɐqɐp

2

他の回答が示唆するように、getargspec照会されるものが実際に関数である限り、うまく機能します。それは動作しません組み込みのような機能openlenなど、そのような場合に例外がスローされます。

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

以下の関数(この回答に触発された)は、回避策を示しています。それはによって期待される引数の数を返しますf

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__文字列から関数仕様を解析することです。明らかに、これは上記の文字列の形式に依存しているため、堅牢ではありません。


2

func.__code__.co_argcountBEFOREの前任意の引数の数を 提供します *args

func.__kwdefaults__あなたの辞書与えキーワード引数を AFTER *args

func.__code__.co_kwonlyargcount 等しい len(func.__kwdefaults__)

func.__defaults__前に現れるオプションの引数の値を与えます *args

これが簡単な図です。

イラスト

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

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上記のコードインチ

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.