HOWTO · Python

関数シグネチャを取得

Python で関数呼び出しの詳細を取得するための短いチュートリアル。

このページの内容

このチュートリアルでは、Python を使用して関数呼び出しの詳細をすばやく取得するためのいくつかの方法について説明します。 これは、大規模なコードベースを分析するときに特に便利で、関数が何をしているかを一目で把握することが難しくなります。

コードを行ったり来たりする代わりに、signature() 関数とデコレータを使用して、この正確な問題に対するよりスマートなソリューションを用意しています。

signature() を使用して Python で関数呼び出しの詳細を取得する

この情報を取得する最も簡単な方法は、inspect.signature() 関数を使用することです。 Python 3.5+ の ドキュメント では、この関数の使用が推奨されています。

inspect.signature() はさまざまな callable を受け入れます。 これには、関数、クラス、および functools.partial() オブジェクトが含まれます。

この関数は、callable の注釈を返します。 署名を提供できない場合、関数は ValueError を発生させます。 オブジェクト タイプがサポートされていない場合は、TypeError が発生します。

コード例:

import inspect


def foo(x, y, a="anything"):
    pass


print(inspect.signature(foo))

端末に次のように表示されます。

(x, y, a="anything")

デコレータを使用して Python で関数呼び出しの詳細を取得する

Python の関数には、利用できるいくつかの属性があります。 これらの属性の中には、__code__ があります。

__code__ 属性にはさらに、使用できる属性があります。 以下に、それらのそれぞれがリストされており、それらが何をするかを説明しています。

その下に、このタスクを実行できる関数を記述するためのコード スニペットを含めます。 __name__ 属性を使用して関数名を取得します。

  1. co_varnames は、関数に渡された引数の名前と関数内で使用されるローカル変数のタプルを返します。

  2. co_argcount は引数の数を返します。 ただし、この数には、キーワードのみの引数 (kwargs)、*args、および **args は含まれません。

    これらの引数をすべて出力する方法をスニペットに含めました。

def get_func_dets(func):
    # the point of using argcount is to ensure we only get
    argument_names = func.__code__.co_varnames[: func.__code__.co_argcount]
    func_name = func.__name__

    # getting variable length arguments and keyword arguments
    def inner_fun(*args, **kwargs):
        print(func_name, "(", end="")

        print(
            ", ".join(
                "%s = %r" % ent
                for ent in zip(argument_names, args[: len(argument_names)])
            ),
            end=", ",
        )

        print("args = ", list(args[len(argument_names) :]), end=",")
        print("kwargs =", kwargs, end="")
        print(")")

    return inner_func