zengbin93 / blog

17 stars 10 forks source link

笔记 - Python - 基础知识 #43

Open zengbin93 opened 5 years ago

zengbin93 commented 5 years ago

记录一些基本语法和实用特性

zengbin93 commented 5 years ago

装饰器

装饰器是闭包的一个特例,可以给原来的函数新增功能。装饰器的输入和输出都是函数。

带参数的装饰器

import functools
from tma.sms import bear_push, server_chan_push

def push2wx(send_key, by="bear"):
    """装饰器:推送消息到微信

    :param send_key: str
        用于发送消息的key
    :param by: str 默认值 bear
        发送消息的方式,默认是bear,
        可选值 ['bear', 'server_chan']
    :return:
    """
    def _wrapper(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            title, content = func(*args, **kw)
            if by == "bear":
                bear_push(title, content, send_key=send_key)
            elif by == "server_chan":
                server_chan_push(title, content, key=send_key)
            else:
                raise ValueError("参数by的可选值为 ['bear', 'server_chan']")
            return title, content
        return wrapper
    return _wrapper

不带参数的装饰器

import functools
import time

def elapsed(func):
    """A decorator for calculating time elapsed when execute func"""
    @functools.wraps(func)
    def wrapper(*args, **kw):
        start = time.time()
        print('Running %s() ...' % func.__name__)
        res = func(*args, **kw)
        end = time.time()
        print('Function %s() running elapsed %.2f s' %
              (func.__name__, end - start))
        return res
    return wrapper

多个装饰器的执行顺序

多个装饰器执行的顺序请查看以下案例;基本规则就是:优先执行靠近函数的装饰器,每个装饰器内部的执行顺序和单个装饰器一样。

def dec1(func):
    print("step 2")
    def one():
        print("step 3")
        func()
        print("step 6")
    return one

def dec2(func):
    print("step 1")
    def two():
        print("step 4")
        func()
        print("step 5")
    return two

@dec1
@dec2
def test():
    print("run function")

if __name__ == "__main__":
    test()