码迷,mamicode.com
首页 > 编程语言 > 详细

Learn Python—函数(装饰器)

时间:2018-01-02 21:25:43      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:timer   开放封闭原则   gpo   blog   语法   too   作用   语法糖   添加   

装饰器

开放封闭原则

开放:对函数的扩展是开放的

封闭:对函数的修改是封闭的

装饰器的作用

在不更改原函数调用方式的前提下,对原函数添加新功能

# ①引子——为什么要有装饰器
为了在不修改原函数的基础上为函数添加新功能,产生了装饰器

# ②简单装饰器
def deco(f):
    def wrapper():
        """原函数前添加的功能"""
        f()
        """原函数后添加的功能"""
    return wrapper

def func():
    print(这是原函数!)

func = deco(func)
func()

# ③装饰器的语法糖
def deco(f):
    def wrapper():
        """原函数前添加的功能"""
        f()
        """原函数后添加的功能"""
    return wrapper

@deco # ——>此处效果等同于 func = deco(func)
def func():
    print(这是原函数)

func()

# ④带返回值的装饰器
def deco(f):
    def wrapper():
        """原函数前添加的功能"""
        res = f()
        """原函数后添加的功能"""
        return res
    return wrapper

@deco
def func():
    print(这是原函数)

func()

# ⑤带参数、带返回值的装饰器
def deco(f):
    def wrapper(*args,**kwargs):
        """原函数前添加的功能"""
        res = f(*args,**kwargs)
        """原函数后添加的功能"""
        return res
    return wrapper

@deco
def func(*args,**kwargs):
    print(这是原函数)

func(*args,**kwargs)

# ⑥多层装饰器
# todo

# ⑦多个装饰器修饰同一个函数
# todo

装饰器的固定格式

def deco(f):
    def wrapper(*args,**kwargs):
    """原函数前添加的功能"""
    res = f(*args,**kwargs)
    """原函数后添加的功能"""
    return res
    return wrapper

@deco
def func(*args,**kwargs):
    pring(这是原函数)

func(*args,**kwargs)

装饰器的固定格式—wraps版

如果想使用原函数的双下方法,则需要再调用系统装饰器@ wraps(func)

from functools import wraps

def deco(func):
    @wraps(func) #加在最内层函数正上方
    def wrapper(*args,**kwargs):
        return func(*args,**kwargs)
    return wrapper

@deco
def origin_func():
    ‘‘‘
    这是原函数的注释
    :return:
    ‘‘‘
    print(这是原函数)

# 虽然已经执行了装饰器,origin_func已经指向wrapper,但是如果用了@wraps(func)装饰器之后调用origin_func的双下方法依然是原函数origin_func的
print(origin_func.__name__)
>>> origin_func

print(origin_func.__doc__)
>>> 这是原函数的注释
>>> :return:

带参数的装饰器

def outer(flag):
    def timer(func):
        def inner(*args,**kwargs):
            if flag:
                print(‘‘‘执行函数之前要做的‘‘‘)
            re = func(*args,**kwargs)
            if flag:
                print(‘‘‘执行函数之后要做的‘‘‘)
            return re
        return inner
    return timer

# 此处先执行函数调用outer(False) —> 返回timer —>@timer —>func = timer(func) —> func = inner
@outer(False) 
def func():
    print(111)

func()

多个装饰器装饰同一个函数

def wrapper1(func):
    def inner1():
        print(wrapper1 ,before func)
        func()
        print(wrapper1 ,after func)
    return inner1

def wrapper2(func):
    def inner2():
        print(wrapper2 ,before func)
        func()
        print(wrapper2 ,after func)
    return inner2

@wrapper2 # 将inner1进行装饰,即inner1 = wrapper2(inner1) = inner2
@wrapper1 # 先执行这个装饰器,即f = wrapper1(f) = inner1
def f():
    print(in f)

f()

# 结果
>>> wrapper2 ,before func
>>> wrapper1 ,before func
>>> in f
>>> wrapper1 ,after func
>>> wrapper2 ,after func

 

Learn Python—函数(装饰器)

标签:timer   开放封闭原则   gpo   blog   语法   too   作用   语法糖   添加   

原文地址:https://www.cnblogs.com/NeroCl/p/8178667.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!