装饰器

一、装饰器的语法:

@装饰器

开放封闭原则:软件实体应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的。

二、装饰器的作用:

在不更改原功能函数内部代码,并且不改变调用方法的情况下为原代码添加新的功能。

三、装饰器的原理:

@decorator 等同于 ===> work1 = decorator(work1)

四、普通装饰器

def decorator(func):
    def wrapper():
        print("---开机,打开软件--")
        func()
        print("---关机,底薪到手---")
    return wrapper

@decorator# 作用 @decorator 等同于 ===> work1 = decorator(work1)
def work1():
    print("----写代码---")
work1()

五、装饰有参数和返回值的餐宿

5-1:实现传参

import time

def count_time(func):
    def wrapper(a,b):
        strat_time = time.time()
        func(a,b)
        end_time = time.time()
        t_time = end_time - strat_time
        print('运行总时间:%s' % t_time)
    return wrapper

@count_time
def work(a,b):
    time.sleep(2)
    e = a + b
    return e
d = work(2,3)
print(d)
image.png

5-2:实现被装饰函数返回值

调用功能函数,接收功能函数返回的结果,装饰器执行完返回结果

def count_time(func):
    def wrapper(a,b):
        # 获取开始时的时间
        strat_time = time.time()
        result = func(a,b)
        end_time = time.time()
        t_time = end_time - strat_time
        print('运行总时间:%s' % t_time)
        return result
    return wrapper

@count_time
def work(a,b):
    time.sleep(2)
    e = a + b
    return e
d = work(2,3)
print(d)
image.png

六:装饰器装饰类

"""
闭包形式的装饰器装饰类:可以在类实例对象的时候,进行功能扩展
"""
"""
闭包形式的装饰器装饰类:可以在类实例对象的时候,进行功能扩展
"""
def decorator(item):
    def wrapper(*args,**kwargs):
        print("装饰器扩展代码1")
        result = item(*args,**kwargs)
        result.name = "木森"
        print("装饰器扩张代码2")
        return result
    return wrapper


@decorator #Mytest = decorator(Mytest)
class Mytest:
    a = 100

print("Mytest:",Mytest)
print()
print("asb",Mytest())
image.png

七:解决装饰器副作用--wraps函数

import time
from functools import wraps
def count_time(fun):
    @wraps(fun)
    def wrapper(*args,**kwargs):
        st = time.time()
        # 调用原功能函数,并使用result接受返回值
        result = fun(*args,**kwargs)
        et = time.time()
        print("函数执行时间:",fun.__name__)
        # 装饰器中的代码执行完后,将原功能函数的结构返回出去
        return result
    return wrapper


@count_time
def work(a,b):
    """work函数"""
    res = a+b
    time.sleep(2)
    return res

@count_time
def work2():
    """work2函数的文档注释"""
    for i in range(3):
        time.sleep(1)

@count_time
def work3(aa,bb,cc,d,e,f,r,y = 999):
    """work3函数的注释"""
    print(aa,bb,cc,d,e,f,r,y)

# print(work(1,2))
# print(work2())
# 装饰器装饰之后会产生的副作用,无法获取原功能函数的特殊属性
print(work.__name__,work.__doc__)
print(work2.__name__,work2.__doc__)
print(work3.__name__,work3.__doc__)
image.png

八:装饰器传参

def decorator(name):
    """最外层的参数,接受装饰器传进来的值"""
    def wrapper2(func):
        """第二层参数func,接收被装饰器的函数"""
        def wrapper3(*args,**kwargs):
            """第三层参数,接受被装饰的函数,被调用时传进来的参数"""
            print("装饰器扩展的功能代码1")
            res = func(*args,**kwargs)
            print("装饰器扩展的功能代码2")
            return res
        return wrapper3
    return wrapper2


@decorator("musen")
def work():
    return "66666666"
print(work())
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一 装饰器介绍 1.1 为何要用装饰器 软件的设计应该遵循开放封闭原则,即对扩展是开放的,而对修改是封闭的。对扩展...
    100斤的瘦子_汤勇阅读 3,624评论 0 0
  • 一、装饰器的基本使用 在不改变函数源代码的前提下,给函数添加新的功能,这时就需要用到“装饰器”。 0.开放封闭原则...
    NJingZYuan阅读 3,499评论 0 0
  • 00. 装饰器简介 在编程领域,有两个原则是必须遵守的,具体就是开放封闭的原则,具体如下: 封闭:已实现的功能代码...
    InsaneLoafer阅读 676评论 0 1
  • 引入 定义函数和定义变量是类似的,变量名绑定的是值的内存地址,而函数名绑定的是代码块的内存地址,函数也可以像变量一...
    程序媛小庄阅读 2,490评论 0 2
  • 闭包 闭包需要满足什么条件?(面试常问)1.函数中嵌套一个函数2.外层函数的返回值是内嵌函数的函数名3.内嵌函数对...
    猪儿打滚阅读 2,972评论 2 0