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

Barbara Streisand
リリース: 2024-10-17 16:58:02
オリジナル
1076 人が閲覧しました

How to Preserve Original Function Signatures when Using Generic Decorators?

汎用デコレータ使用時の元の関数のシグネチャの保持

問題の概要

デコレータは追加機能で関数を拡張できますが、多くの場合、汎用デコレータが元の関数を置き換えます。 「args、*kwargs」のようなワイルドカード署名を使用した署名。これは、特にドキュメントを生成したり、関数のメタデータをイントロスペクトしたりする場合に問題になる可能性があります。

解決策 1: デコレータ モジュールの利用

デコレータ モジュールは簡単な解決策を提供します。デコレータ関数をdecorator.decoratorでラップすることで、元の関数の署名を維持できます:

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

@args_as_ints
def funny_function(x, y, z=3):
    """Computes x*y + 2*z"""
    return x*y + 2*z</code>
ログイン後にコピー

このアプローチでは、元の関数の署名が維持されます:

<code class="python">help(funny_function)
# Help on function funny_function in module __main__:
# 
# funny_function(x, y, z=3)
#     Computes x*y + 2*z</code>
ログイン後にコピー

解決策 2: 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

@args_as_ints
def funny_function(x, y, z=3):
    """Computes x*y + 2*z"""
    return x*y + 2*z

help(funny_function)
# Help on function funny_function in module __main__:
#
# funny_function(x, y, z=3)
#     Computes x*y + 2*z</code>
ログイン後にコピー

ただし、functools.wraps() は、Python の以前のバージョンではこの動作を示しませんでした。 .

その他のアプローチ

関数の docstring で署名を複製したり、特定の署名ごとにカスタム デコレータを作成したりすることは、重複とメンテナンスの問題を引き起こす欠陥のある回避策です。

結論

デコレータ モジュールを利用するか、Python 3.4 の functools.wraps() を利用することで、元の関数のシグネチャを維持しながらデコレータを汎用的に使用でき、堅牢なドキュメントとイントロスペクション機能が確保されます。

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

ソース:php
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート