cover_effective_python

【 Effective Python, 2nd Edition 】再帰関数の実行順序をトレースするデコレータを実装しよう - デバック用途にも重宝します! 投稿一覧へ戻る

Tags: Python , Effective , decorator , recursive

Published 2020年6月24日21:04 by T.Tsuyoshi

今回もデコレータに関連する話題ですが、デコレータの詳細については 前回 取り上げましたので、
今回は復習も兼ねながらちょっと面白いプログラムをご紹介します。


このプログラムは、再帰関数 (recursive function) のネスト呼び出し時における実行過程を、各時点の引数と返却値と共に表示するものです。


fibonacci(4) を実行した際の表示は次のようになります。
(フィボナッチ数については wikipedia を参考にしてください )

fibonacci((0,), {}) -> 0
fibonacci((1,), {}) -> 1
fibonacci((2,), {}) -> 1
fibonacci((1,), {}) -> 1
fibonacci((0,), {}) -> 0
fibonacci((1,), {}) -> 1
fibonacci((2,), {}) -> 1
fibonacci((3,), {}) -> 2
fibonacci((4,), {}) -> 3



再帰関数、と聞くだけで結構目が回りますが、結果を確かめようと実際にコードを追うと !! イライラMAX !! という方も多いと思います。
デバッグ目的の情報としては非常に有益なものだと思いますので、イライラを募らせながら解析してみてください。


from functools import wraps


def trace(func):
@wraps(func)
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
print(f"{func.__name__}({args!r}, {kwargs!r}) -> {result!r}")
return result
return wrapper


@trace
def fibonacci(n):
"""n 番目のフィボナッチ数を返します"""
if n in (0, 1):
return n
return (fibonacci(n - 2) + fibonacci(n - 1))


fibonacci(4)

print(fibonacci)

# <function fibonacci at 0x0000000001E46A60>



print(fibonacci.__name__)

# fibonacci



print(fibonacci.__doc__)

# n 番目のフィボナッチ数を返します



help(fibonacci)

# Help on function fibonacci in module __main__:
#
# fibonacci(n)
# n 番目のフィボナッチ数を返します




import pickle

print(pickle.dumps(fibonacci))

# b'\x80\x04\x95\x1a\x00\x00\x00\x00\x00\x00\x00\x8c\x08__main__\x94\x8c\tfibonacci\x94\x93\x94.'

この投稿をメールでシェアする

0 comments

コメントはまだありません。

コメントを追加する(不適切と思われるコメントは削除する場合があります)