【 Effective Python, 2nd Edition 】再帰関数の実行順序をトレースするデコレータを実装しよう - デバック用途にも重宝します! 投稿一覧へ戻る
Published 2020年6月24日21:04 by mootaro23
SUPPORT UKRAINE
- Your indifference to the act of cruelty can thrive rogue nations like Russia -
今回もデコレータに関連する話題ですが、デコレータの詳細については 前回 取り上げましたので、
今回は復習も兼ねながらちょっと面白いプログラムをご紹介します。
このプログラムは、再帰関数 (recursive function) のネスト呼び出し時における実行過程を、各時点の引数と返却値と共に表示するものです。
fibonacci(4) を実行した際の表示は次のようになります。
(フィボナッチ数については wikipedia を参考にしてください )
再帰関数、と聞くだけで結構目が回りますが、結果を確かめようと実際にコードを追うと !! イライラMAX !! という方も多いと思います。
デバッグ目的の情報としては非常に有益なものだと思いますので、イライラを募らせながら解析してみてください。
今回は復習も兼ねながらちょっと面白いプログラムをご紹介します。
このプログラムは、再帰関数 (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
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)
print(fibonacci.__name__)
print(fibonacci.__doc__)
help(fibonacci)
import pickle
print(pickle.dumps(fibonacci))
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.'
この記事に興味のある方は次の記事にも関心を持っているようです...
- People who read this article may also be interested in following articles ... -