次のような素晴らしい小さな関数があります。
def verbose_print(message, *args, **kwargs):
"""Prints `message` with a helpful prefix when in verbose mode
Args:
message (str): The message to print. Can be a format string, e.g.
`A %s with some %s in it`
*args: Variables for the message format
**kwargs: Keyword variables for the message format
"""
# Only print when in verbose mode
if not config.verbose:
return
# Ready a prefix for the message
try:
s = inspect.stack()
module_name = inspect.getmodule(s[1][0]).__name__
func_name = s[1][3]
prefix = '### %s->%s' % (module_name, func_name)
except Exception as e:
prefix = '### [stack unavailable]'
if args:
message = message % args
elif kwargs:
message = message % kwargs
print '%s: %s' % (prefix, message)
関数のポイントは、メッセージを使用してどこからでも呼び出すことができることです。プロジェクト構成ファイルが詳細モードに設定されている場合、すべてのメッセージは、呼び出された場所を示す便利なプレフィックスと共に出力されます。出力の例を次に示します。
### avesta.webserver->check_login: 127.0.0.1 でクライアントのログインを確認しています ### avesta.webserver->check_login: ユーザー名: tomas、トークン: blablabla の資格情報 Cookie が見つかりました ### avesta.webserver->check_login: ログイン有効、更新セッション ### avesta.webserver->get_flash_memory: 取得したフラッシュ データ: なし ### avesta.webserver->get: 空のパス ('previous_values', 'name') からデータを取得し、'' を返しました ### avesta.webserver->get: 空のパス ('previous_values', 'description') からデータを取得し、'' を返しました ### avesta.webserver->get: 空のパス ('validation_errors', 'name') からデータを取得し、'' を返しました
フォーマットは"### module->function: message"です。
ほとんどの場合、これは本当に役に立ちますが、完全ではありません。上記の例では、「get」関数は実際にはクラスのバインドされたメソッドですが、それは表示されません。私が達成しようとしているのは、関数がバインドされたメソッドである場合、代わりに次の形式で出力することです。
「###モジュール->クラス名.関数」
しかし、問題は次のとおりです。
- スタックから関数名を取得するだけなので、バインドされたメソッドかどうかを実際に確認することはできません
- 関数参照があったとしても、それがバインドされているクラス名をどのように推測するのでしょうか?
これを理解するのに役立つ回答をありがとう。