[解決済み] functools.wrapsの機能は何ですか?
2022-03-21 03:14:10
質問
この記事へのコメントで
別質問に対する回答
がよくわからないとおっしゃる方がいました。
functools.wraps
がやっていた。そこで、今後の参考のためにStackOverflowに記録しておくために、この質問をします。
functools.wraps
は、具体的にどうするのですか?
どのように解決するのですか?
デコレーターを使うということは、ある関数を別の関数に置き換えるということです。 つまり、もしデコレーターが
def logged(func):
def with_logging(*args, **kwargs):
print(func.__name__ + " was called")
return func(*args, **kwargs)
return with_logging
という場合は
@logged
def f(x):
"""does some math"""
return x + x * x
というのと全く同じです。
def f(x):
"""does some math"""
return x + x * x
f = logged(f)
という関数があります。
f
は関数に置き換えられます。
with_logging
. 残念ながら、このことは、もしあなたが
print(f.__name__)
と表示されます。
with_logging
なぜなら、それが新しい関数の名前だからです。 実際、この関数のdocstringを見ると
f
のため、空白になります。
with_logging
はdocstringを持たないので、あなたが書いたdocstringはもうそこにはありません。 また、その関数のpydocの結果を見ると、1つの引数を取るものとしてリストアップされていません。
x
代わりに
*args
と
**kwargs
というのも、with_loggingが取るのはこれだからです。
もし、デコレータを使うことで常にこのような関数に関する情報が失われるとしたら、それは深刻な問題でしょう。 そのため、私たちは
functools.wraps
. これは、デコレータで使用されている関数を受け取り、関数名、docstring、引数リストなどをコピーオーバーする機能を追加するものです。 そして
wraps
はそれ自体がデコレーターなので、次のコードは正しい処理を行います。
from functools import wraps
def logged(func):
@wraps(func)
def with_logging(*args, **kwargs):
print(func.__name__ + " was called")
return func(*args, **kwargs)
return with_logging
@logged
def f(x):
"""does some math"""
return x + x * x
print(f.__name__) # prints 'f'
print(f.__doc__) # prints 'does some math'
関連
-
[解決済み】Python Error: "ValueError: need more than 1 value to unpack" (バリューエラー:解凍に1つ以上の値が必要です
-
[解決済み】Flaskのテンプレートが見つからない【重複あり
-
[解決済み] 文字列リテラルの前にある'b'文字は何を意味するのでしょうか?
-
[解決済み] PandasでDataFrameの行を反復処理する方法
-
[解決済み] 最小限の驚き」と「変更可能なデフォルトの引数
-
[解決済み] パラメータに**(ダブルスター/アスタリスク)、*(スター/アスタリスク)がありますが、これはどういう意味ですか?
-
[解決済み] なぜC++はPythonよりもstdinからの行の読み込みが遅いのですか?
-
[解決済み] インスタンスのクラス名を取得する?
-
[解決済み】if __name__ == "__main__": は何をするのでしょうか?
-
[解決済み】Pythonに三項条件演算子はありますか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
python call matlab メソッドの詳細
-
pythonサイクルタスクスケジューリングツール スケジュール詳解
-
Python 可視化 big_screen ライブラリ サンプル 詳細
-
Pythonを使って簡単なzipファイルの解凍パスワードを手作業で解く
-
パッケージングツールPyinstallerの使用と落とし穴の回避
-
[解決済み】ilocが「IndexError: single positional indexer is out-of-bounds」を出す。
-
[解決済み】socket.error: [Errno 48] アドレスはすでに使用中です。
-
[解決済み】TypeError: 系列を <class 'float'> に変換することができません。
-
[解決済み】Flaskのテンプレートが見つからない【重複あり
-
[解決済み] クラスの飾りつけはどうする?