パラメータ付きアクセラレータを定義するには
1665 ワード
パラメータ付きアクセラレータを定義するには
に質問
パラメータを受け入れる装飾器を定義したいのですが
ソリューション
パラメータを受け入れる処理過程を一例で詳細に述べた.デザイナを書き、関数にログ機能を追加し、ユーザーがログのレベルと他のオプションを指定できるようにするとします.以下に、この装飾品の定義と使用例を示します.
最初は、このような実現は複雑に見えたが、核心思想は簡単だった.最外層の関数
ディスカッション
パラメータを受け入れるパッケージを定義するのは、主に最下位の呼び出しシーケンスのために複雑に見えます.特に、次のコードがあれば、
装飾器の処理過程は以下の呼び出しと等価である.
に質問
パラメータを受け入れる装飾器を定義したいのですが
ソリューション
パラメータを受け入れる処理過程を一例で詳細に述べた.デザイナを書き、関数にログ機能を追加し、ユーザーがログのレベルと他のオプションを指定できるようにするとします.以下に、この装飾品の定義と使用例を示します.
from functools import wraps
import logging
def logged(level, name=None, message=None):
"""
Add logging to a function. level is the logging
level, name is the logger name, and message is the
log message. If name and message aren't specified,
they default to the function's module and name.
"""
def decorate(func):
logname = name if name else func.__module__
log = logging.getLogger(logname)
logmsg = message if message else func.__name__
@wraps(func)
def wrapper(*args, **kwargs):
log.log(level, logmsg)
return func(*args, **kwargs)
return wrapper
return decorate
# Example use
@logged(logging.DEBUG)
def add(x, y):
return x + y
@logged(logging.CRITICAL, 'example')
def spam():
print('Spam!')
最初は、このような実現は複雑に見えたが、核心思想は簡単だった.最外層の関数
logged()
は、パラメータを受け入れ、内部の装飾関数に作用する.内層の関数decorate()
は、パラメータとして関数を受け入れ、その後、関数の上にパッケージを配置する.ここで重要な点は、パッケージがlogged()
に渡されるパラメータを使用することができることである.ディスカッション
パラメータを受け入れるパッケージを定義するのは、主に最下位の呼び出しシーケンスのために複雑に見えます.特に、次のコードがあれば、
@decorator(x, y, z)
def func(a, b):
pass
装飾器の処理過程は以下の呼び出しと等価である.
def func(a, b):
pass
func = decorator(x, y, z)(func)
decorator(x, y, z)
の戻り結果は、パラメータとして関数を受け入れてパッケージする呼び出し可能なオブジェクトである必要があります.9.7節の他のパラメータを受け入れるパッケージの例を参照してください.