ホームページ  >  記事  >  バックエンド開発  >  Python でデコレータを使用するときに関数のシグネチャを保持するにはどうすればよいですか?

Python でデコレータを使用するときに関数のシグネチャを保持するにはどうすればよいですか?

DDD
DDDオリジナル
2024-10-17 16:59:58446ブラウズ

How to Preserve Function Signatures When Using Decorators in Python?

装飾された関数の署名の保持

デコレーターは、Python 関数の機能を拡張するための強力なツールです。ただし、元の関数の署名がわかりにくくなる場合があります。これは、ドキュメント、デバッグ、および自動化ツールにとって問題となる可能性があります。

問題:

すべての引数を整数に変換する汎用デコレータを考えてみましょう:

<code class="python">def args_as_ints(f):
    def g(*args, **kwargs):
        args = [int(x) for x in args]
        kwargs = dict((k, int(v)) for k, v in kwargs.items())
        return f(*args, **kwargs)
    return g</code>

装飾は期待どおりに機能しますが、装飾された関数のシグネチャは「args, *kwargs」に置き換えられ、元の引数に関する情報が失われます。

回避策:

いくつかの回避策が存在しますが、完全に満足できるものはありません:

  • 署名を docstring に手動でコピーする。
  • 特定の署名ごとに新しいデコレーターを作成する。
  • exec を使用して装飾された関数を手動で構築する

解決策:

デコレータ モジュールは洗練された解決策を提供します:

<code class="python">import decorator

@decorator.decorator
def args_as_ints(f, *args, **kwargs):
    args = [int(x) for x in args]
    kwargs = dict((k, int(v)) for k, v in kwargs.items())
    return f(*args, **kwargs)</code>

このデコレータは、ラップされた関数に引数として渡すことで、元の関数のシグネチャを保持します。

改良されたデコレータ:

<code class="python">@args_as_ints
def funny_function(x, y, z=3):
    """Computes x*y + 2*z"""
    return x*y + 2*z</code>

装飾された関数 funny_function は、保持されます。元の署名:

>>> help(funny_function)
Help on function funny_function in module __main__:

funny_function(x, y, z=3)
    Computes x*y + 2*z

Python 3.4 :

Python 3.4 以降の場合、functools.wraps は同様のソリューションを提供します:

<code class="python">import functools

def args_as_ints(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        args = [int(x) for x in args]
        kwargs = dict((k, int(v)) for k, v in kwargs.items())
        return func(*args, **kwargs)
    return wrapper</code>

これらの手法を使用することで、デコレータは元の署名を維持しながら関数の機能を強化し、コードベースの明確さと一貫性を確保できます。

以上がPython でデコレータを使用するときに関数のシグネチャを保持するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。