python装饰器

六眼飞鱼酱① 提交于 2020-02-17 00:06:44
装饰器:给已有函数增加额外功能的函数,它本质上就是一个闭包函数。
在不改变已有函数源代码及调用方式的前提下,对已有函数进行功能的扩展。
特点:
    不修改已有函数的源代码
    不修改已有函数的调用方式
    给已有函数增加额外的功能
# 装饰器的基本雏形
# def decorator(fn): # fn:目标函数.
#     def inner():
#         print('''执行函数之前''')
#         fn() # 执行被装饰的函数
#         print('''执行函数之后''')
#     return inner
# 添加一个登录验证的功能
def check(fn):
    def inner():
        print("请先登录....")
        fn()
    return inner


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


def check_out(fn):
    
    def inner():
        # 先执行检测代码
        print("检测用户是否合法登录........")
        fn()

    return inner

# 语法糖写法
# 修饰 @check_out 等价于 work = check_out(work)
@check_out
def work():
    print("正常工作")

work()
# 使用装饰器来装饰函数

comment = check(comment)
comment()

装饰器实现已有函数执行时间的统计

import time

# 装饰器函数
def get_time(func):
    def inner():
        begin = time.time()
        func()
        end = time.time()
        print("函数执行花费%f" % (end-begin))
    return inner


@get_time
def func1():
    for i in range(100000):
        print(i)


func1()

装饰器的使用方式

# 装饰带有参数的函数
# 添加输出日志的功能
def logging(fn):
    def inner(num1, num2):
        print("--正在努力计算--")
        fn(num1, num2)
        print("--计算完成--")

    return inner


# 使用装饰器装饰函数
@logging
def sum_num(a, b):
    result = a + b
    print(result)


sum_num(1, 2)
# 添加输出日志的功能
def logging(fn):
    def inner(num1, num2):
        print("--正在努力计算--")
        result = fn(num1, num2)
        return result
    return inner


# 使用装饰器装饰函数
@logging
def sum_num(a, b):
    result = a + b
    return result


result = sum_num(1, 2)
print(result)
# 完成不定长参数的装饰
# 添加输出日志的功能
def logging(fn):
    def inner(*args,**kwargs):
        print("--正在努力计算--")
        result = fn(*args,**kwargs)
        print("计算结束")
        return result
    return inner


# 使用装饰器装饰函数
@logging
def sum_num(*args,**kwargs):
    result = 0
    for i in args:
        result+=i
    for value in kwargs.values():
        result+=value
    return result


result = sum_num(1, 2,3,4,5,6,a=2,b=3,c=5)
print(result)

多重装饰器的装饰

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 "人生苦短,我用python"
# 多个装饰器的装饰过程是: 离函数最近的装饰器先装饰,然后外面的装饰器再进行装饰,由内到外的装饰过程
result = content()

print(result)

装饰器带有参数

# 添加输出日志的功能
def logging(flag):

    def decorator(fn):
        def inner(num1, num2):
            if flag == "+":
                print("--正在努力加法计算--")
            elif flag == "-":
                print("--正在努力减法计算--")
            else:
                print("没有这个符号呀")
            result = fn(num1, num2)
            return result
        return inner

    # 返回装饰器
    return decorator


# 使用装饰器装饰函数
@logging("+")
def add(a, b):
    result = a + b
    return result


@logging("-")
def sub(a, b):
    result = a - b
    return result

result = add(1, 2)
print(result)

result = sub(1, 2)
print(result)

类装饰器

# 适用于类装饰函数
class Check(object):
    
    def __init__(self, fn):
        # 初始化操作在此完成
        self.__fn = fn

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


@Check
def comment():
    print("发表评论")


comment()
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!