14-装饰器

导读:装饰器——在不更改原函数的代码的前提下给函数增加新的功能,特殊之处在于它的返回值也是一个函数。话不多说,上代码体验!

闭包示例代码

def fun1(name1):
    def fun2(name2):  # 4.hello传到这儿了,函数这东西不调用就不执行
        print(name1 + name2)

    print('2')  # 1.上面函数没调用就不执行,直接从这儿开始
    return fun2  # 2写的是函数名,返回地址


a = fun1('tom')
a('hello')  # 3指向fun1的返回值即fun2('hello')
a('hi')  # 5同上

通过闭包更改外部函数值用nonlocal arg

def func_out(num1):
    def func_inner(num2):
        nonlocal num1  # 可以改变这个值
        num1 = num1 + num2
        print("num1:", num1)

    print(num1)
    func_inner(1)  # 之所以这样,因为得跑一遍才能改呀,直接打印num1,数据流没跑到那儿肯定没修改。
    print(num1)
    return func_inner


f = func_out(1)
f(2)

装饰器基础结构

def check(fn):
    def inner():
        print("请先登录....")
        fn()  # 5指向comment()

    return inner  # 1指向下面的调用者comment


def comment():
    print("发表评论")  # 6


comment = check(comment)  # 2 comment装的是inner函数的地址。可改成@check即装饰器,放在被装饰方法comment()的上方。
comment()  # 3指向inner()

装饰器案例-时间统计

import time


def outer(func):
    def inner():
        star_time = time.time()
        func()
        end_time = time.time()
        print('花费时间:%f' % (end_time - star_time))

    return inner


@outer
def func():
    for i in range(9):
        print(i)


func()

通用装饰器

(包含了不定长参数、带返回值函数;多debug,先执行两个装饰器,跑没头了,给调用它的人)

def logging(fn):
    def inner(*args, **kwargs):
        print("--正在努力计算--")
        result = fn(*args, **kwargs)  # 藏的有点深啊,所以下面不必再写sum_num()这个指向inner的方法。
        return result

    return inner


@logging
def sum_num(*args, **kwargs):
    result = 0
    for value in args:
        result += value
        print(result)
    for value in kwargs.values():
        result += value
        print(result)
    return result


@logging
def subtraction(a, b):
    result = a - b
    print(result)


result = sum_num(1, 2, a=10)
print(result)
subtraction(4, 2)

类装饰器

class Check(object):
    def __init__(self, fn):
        # 初始化操作在此完成
        self.__fn = fn

    # 实现__call__方法,表示对象是一个可调用对象,可以像调用函数一样进行调用。
    def __call__(self, *args, **kwargs):
        # 添加装饰功能
        print("请先登陆...")
        self.__fn('sdf')
@Check
def comment():
    print("发表评论")
comment()

check=Check(print)    #也可以改input,拓展:上面args[0]('注册')表示print('注册'),间接表明一切皆对象。
check()

多装饰器

def make_div(func):
    """对被装饰的函数的返回值 div标签"""

    def inner(*args, **kwargs):
        return "<div>" + func() + "</div>"

    return inner


def make_p(func):
    """对被装饰的函数的返回值 p标签"""

    def inner(*args, **kwargs):
        return "<p>" + func() + "</p>"

    return inner


# 装饰过程: 1 content = make_p(content) 2 content = make_div(content)
# content = make_div(make_p(content))
@make_div
@make_p
def content():
    return "你好哈哈"


result = content()
print(result)

 

上一篇:left join,right join以及inner join的区别


下一篇:Java内部类