python 装饰器三

2020-05-11  本文已影响0人  三元一只十元三只
import time

def log(func):
    def wrapper(*args, **kw):
        print('func %s() is running' % func.__name__)
        return  func(*args, **kw)
    return wrapper

@log
def now():
    print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

这是上一篇文章中用来分析的例子。完整的写法应该是

import time

def log(func):
    def wrapper(*args, **kw):
        print('func %s() is running' % func.__name__)
        return  func(*args, **kw)
    return wrapper

now = log(now)
def now():
    print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

之前我们学习高阶函数的时候了解到了高阶函数的特征之一就是它接收一个函数作为其参数。 现在我们补充另一个点就是,高阶函数不仅接收函数作为参数,它还能将函数作为结果返回。
例如:

def lazy_sum(*args):
    def sum():
        ax = 0
        for a in args:
            ax = ax + a
        return ax
    return sum

# 当调用lazy_sum时,返回的是求和函数而不是结果
f = lazy_sum(1,2,3,3,4,5)
# 此时 打印 f 会得到一个函数
print(f)
#<function lazy_sum.<locals>.sum at 0x101c6ed90>
# 如果我们要获取到 lazy_sum 的结果。可以调用 f
f()

我们每次调用 lazy_sum() 函数,都会得到一个新的函数,即时传入的参数相同,得到的结果也是不同的
现在回头看我们的装饰器 不用语法糖 @ 符号的写法
首先装饰器函数 log

def log(func):
    def wrapper(*args, **kw):
        print('func %s() is running' % func.__name__)
        return  func(*args, **kw)
    return wrapper

它接收一个函数,并且再其内部定一个了一个wrapper 函数,并将 wrapper 函数作为结果返回。
再来看调用装饰器的方法

...
now = log(now)
# 第一个 now 是变量名。 log方法中的 now 是下面定义的函数 now, 它被作为 参数传入到 log 方法中。
def now():
    print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

我们是直接将 log 的返回赋值给了跟 函数 now() 同名的变量 now, 这么做就是为了后面的使用中不用再重复命名。

上一篇下一篇

猜你喜欢

热点阅读