装饰器用来跟踪函数调用

1.装饰器跟踪 【简单裴波那契数列】

# coding=utf-8
def trace(f):
    f.indent = 0

    def g(x):
        print(f"{' | ' * f.indent} |-- {f.__name__} {x}")
        f.indent += 1
        result = f(x)
        print(f"{' | ' * f.indent} |-- Return {repr(result)}")
        f.indent -= 1
        return result

    return g


@trace
def fib(n):
    if n < 2:
        return 1
    else:
        return fib(n - 1) + fib(n - 2)


print(fib(5))

输出:
 |-- fib 5
 |  |-- fib 4
 |  |  |-- fib 3
 |  |  |  |-- fib 2
 |  |  |  |  |-- fib 1
 |  |  |  |  |  |-- Return 1
 |  |  |  |  |-- fib 0
 |  |  |  |  |  |-- Return 1
 |  |  |  |  |-- Return 2
 |  |  |  |-- fib 1
 |  |  |  |  |-- Return 1
 |  |  |  |-- Return 3
 |  |  |-- fib 2
 |  |  |  |-- fib 1
 |  |  |  |  |-- Return 1
 |  |  |  |-- fib 0
 |  |  |  |  |-- Return 1
 |  |  |  |-- Return 2
 |  |  |-- Return 5
 |  |-- fib 3
 |  |  |-- fib 2
 |  |  |  |-- fib 1
 |  |  |  |  |-- Return 1
 |  |  |  |-- fib 0
 |  |  |  |  |-- Return 1
 |  |  |  |-- Return 2
 |  |  |-- fib 1
 |  |  |  |-- Return 1
 |  |  |-- Return 3
 |  |-- Return 8
8

2.装饰器跟踪 【优化裴波那契数列】

def trace2(f):
    cache = {}
    f.indent = 0
    def g(*args):
        if args not in cache:
            print(f"{' | ' * f.indent} |-- {f.__name__} {args}")
            f.indent += 1
            cache[args] = f(*args)
            print(f"{' | ' * f.indent} |-- Return {repr(cache[args])}")
            f.indent -= 1
        return cache[args]

    return g


@trace2
def fib2(n):
    if n < 2:
        return 1
    else:
        return fib2(n - 1) + fib2(n - 2)


%time fib2(20)
输出:
 |-- fib2 (20,)
 |  |-- fib2 (19,)
 |  |  |-- fib2 (18,)
 |  |  |  |-- fib2 (17,)
 |  |  |  |  |-- fib2 (16,)
 |  |  |  |  |  |-- fib2 (15,)
 |  |  |  |  |  |  |-- fib2 (14,)
 |  |  |  |  |  |  |  |-- fib2 (13,)
 |  |  |  |  |  |  |  |  |-- fib2 (12,)
 |  |  |  |  |  |  |  |  |  |-- fib2 (11,)
 |  |  |  |  |  |  |  |  |  |  |-- fib2 (10,)
 |  |  |  |  |  |  |  |  |  |  |  |-- fib2 (9,)
 |  |  |  |  |  |  |  |  |  |  |  |  |-- fib2 (8,)
 |  |  |  |  |  |  |  |  |  |  |  |  |  |-- fib2 (7,)
 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |-- fib2 (6,)
 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |-- fib2 (5,)
 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |-- fib2 (4,)
 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |-- fib2 (3,)
 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |-- fib2 (2,)
 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |-- fib2 (1,)
 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |-- Return 1
 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |-- fib2 (0,)
 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |-- Return 1
 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |-- Return 2
 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |-- Return 3
 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |-- Return 5
 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |-- Return 8
 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |-- Return 13
 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |-- Return 21
 |  |  |  |  |  |  |  |  |  |  |  |  |  |-- Return 34
 |  |  |  |  |  |  |  |  |  |  |  |  |-- Return 55
 |  |  |  |  |  |  |  |  |  |  |  |-- Return 89
 |  |  |  |  |  |  |  |  |  |  |-- Return 144
 |  |  |  |  |  |  |  |  |  |-- Return 233
 |  |  |  |  |  |  |  |  |-- Return 377
 |  |  |  |  |  |  |  |-- Return 610
 |  |  |  |  |  |  |-- Return 987
 |  |  |  |  |  |-- Return 1597
 |  |  |  |  |-- Return 2584
 |  |  |  |-- Return 4181
 |  |  |-- Return 6765
 |  |-- Return 10946
Wall time: 3 ms
10946

跟踪 【计算指数】

def trace(f):
    f.indent = 0

    def g(*args):
        if args[1] % 2 == 0:
            print(f"{' |    ' * f.indent} +-- {args[0]} * {f.__name__} {args}")
        else:
            print(f"{' |    ' * f.indent} +-- {f.__name__} {args}")
        f.indent += 1
        result = f(*args)
        f.indent -= 1
        print(f"{' |    ' * f.indent} +-- Return {result}")
        return result

    return g


@trace
def fast_exp(x, n):  # 计算指数
    if n == 0:
        return 1
    elif n % 2 == 0:  # 2的倍数
        return fast_exp(x * x, n / 2)
    else:  # 不是2的倍数
        return x * fast_exp(x, n - 1)


fast_exp(2, 10)


输出:
 +-- 2 * fast_exp (2, 10)
 |     +-- fast_exp (4, 5.0)
 |     |     +-- 4 * fast_exp (4, 4.0)
 |     |     |     +-- 16 * fast_exp (16, 2.0)
 |     |     |     |     +-- fast_exp (256, 1.0)
 |     |     |     |     |     +-- 256 * fast_exp (256, 0.0)
 |     |     |     |     |     +-- Return 1
 |     |     |     |     +-- Return 256
 |     |     |     +-- Return 256
 |     |     +-- Return 256
 |     +-- Return 1024
 +-- Return 1024
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值