44. 使用函数装饰器

某些时候我们想问多个函数统一添加某种功能,比如计时统计、记录日志、缓存运算结果等等。我们不想在每个函数内添加完全相同的代码,如何更好的达成目的呢?

要求:不在每个函数内添加完全相同的代码的前提下实现功能。

解决方案:

定义装饰器函数,用它生成一个在原函数基础上添加了新功能的函数,替代原函数。


  • 对于装饰器decorator:

Python的装饰器decorator本质上是一个高阶函数,它接收一个函数作为参数,然后返回一个新的函数,可以让该函数在不改动源代码的情况下增加其他新功能。

Python通过一个语法糖@符号来使用decorator,这样可以避免编写f = decorate(f)这样形式的代码。所谓的语法糖便是你不使用也可以完成任务,但是使用它可以让你的代码更简洁。

对于装饰器,需要记住的就是

@decorate
def f():
    pass

其中,

@decorate   等价于  f = decorate(f)

  • 方案示例:
1. 斐波那契数列

def fib(n):
    if n <= 1:
        return 1
    return fib(n-1) + fib(n-2)

print(fib(50))

2. 走台阶问题
# 台阶有100阶,一个人每次可以走1~3阶。有多少种走法?

def climb(n, steps):
    count = 0
    if n == 0:
        count = 1
    elif n > 0:
        for step in steps:
            count += climb(n-step, steps)
    return count

print(climb(100, (1, 2, 3)))

对于求斐波那契数列,递归过程中会反复求值,造成算法效率低;走台阶问题也是如此。

如何提高上面两函数的算法效率,可以通过装饰器函数来缓存运算结果。

def memo(func):
    cache = {}
    def wrap(*args):
        res = cache.get(args)
        if not res:
            res = cache[args] = func(*args)
        return res
    return wrap

@memo               #等价于 fib = memo(fib)
def fib(n):
    if n <= 1:
        return 1
    return fib(n-1) + fib(n-2)

print(fib(50))

@memo               #等价于 climb = memo(climb)
def climb(n, steps):
    count = 0
    if n == 0:
        count = 1
    elif n > 0:
        for step in steps:
            count += climb(n-step, steps)
    return count

print(climb(100, (1, 2, 3)))

结果:

20365011074
180396380815100901214157639

有了装饰器函数装饰之后,会很快得到运算结果,大大提高了算法效率。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值