装饰器

装饰器

开放封闭原则:

什么是开放封闭原则?有的同学问开放,封闭这是两个反义词这还能组成一个原则么?这不前后矛盾么?其实不矛盾。开放封闭原则是分情况讨论的。

​ 我们的软件一旦上线之后(比如你的软件主要是多个函数组成的),那么这个软件对功能的扩展应该是开放的,比如你的游戏一直在迭代更新,推出新的玩法,新功能。但是对于源代码的修改是封闭的。你就拿函数举例,如果你的游戏源代码中有一个函数是闪躲的功能,那么你这个函数肯定是被多个地方调用的,比如对方扔手雷,对方开枪,对方用刀,你都会调用你的闪躲功能,那么如果你的闪躲功能源码进行改变了,或者调用方式改变了,当对方发起相应的动作,你在调用你的闪躲功能,就会发生问题。所以,开放封闭原则具体定义是这样:

1.对扩展是开放的(增加新功能)

​ 我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。

2.对修改是封闭的(修改已经实现的功能)

​ 就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对函数内部进行修改,或者修改了函数的调用方式,很有可能影响其他已经在使用该函数的用户。OK,理解了开封封闭原则之后,我们聊聊装饰器。

​ 什么是装饰器?从字面意思来分析,先说装饰,什么是装饰? 装饰就是添加新的,

​ 比如我现在不会飞,怎么才能让我会飞?给我额外增加一个翅膀,我就能飞了。那么你给我加一个翅膀,它会改变我原来的行为么?我之前的吃喝拉撒睡等生活方式都不会改变。它就是在我原来的基础上,添加了一个新的功能。

今天我们讲的装饰器(翅膀)是以功能为导向的,就是一个函数。

被装饰的对象:我本人,其实也是一个函数。

所以装饰器最终最完美的定义就是:在不改变原被装饰的函数的源代码以及调用方式的基础下,额外增加新的的功能。

装饰器: 用来装饰的工具 ---开放封闭原则

作用:在不修改源函数及调用方式前提下额外增加一些功能

函数嵌套:

闭包

简单版的装饰器

版一:

import time
# print(time.time())#格林尼治时间
start_time  =time.time()
def func():
    time.sleep(2)#睡眠模拟网络延迟
    print("我要飞")
func()
end_time = time.time()
print(end_time-start_time)

版本二

import time
def times(f):
    start_time = time.time()
    f()
    print(time.time() - start_time)

def foo():
    time.sleep(3) #睡眠 (模拟网络延时)
    print("我是小明,我飞的比你高")

def func():
    time.sleep(1) #睡眠 (模拟网络延时)
    print("我是业儿,我起不来")
s = func
func = times

s = foo
foo = times
foo(s)

版本三(装饰器初始)

import time
def times(f):
    def inner():
        start_time = time.time()
        f()
        print(time.time() - start_time)
    return inner

def foo():
    time.sleep(1) #睡眠 (模拟网络延时)
    print("我是李业,我快!")

foo = times(foo)
foo()

版本四(第二版装饰器)

def wrapper(f):
    def inner():
        f()
    return inner  # 切记不要加括号

def func():
    print("这是func函数,李业还是不行")
func = wrapper(func)
func()
结果
这是func函数,李业还是不行

def wrapper(f):
    def inner(*args,**kwargs):
        f(*args,**kwargs) # func("alex")
    return inner  # 切记不要加括号


def func(*args,**kwargs):
    print(f"这是{args}和{kwargs}函数,李业还是不行")


func = wrapper(func)
func("alex","sur",a = 1,b=2,c="cqk")
结果
这是('alex', 'sur')和{'a': 1, 'b': 2, 'c': 'cqk'}函数,李业还是不行

# low版
import time
def wrapper(f):
    def inner(*args,**kwargs):
        "被装饰前"
        start_time = time.time()
        f(*args,**kwargs) # func("alex")
        print(time.time() - start_time)
        "被装饰后"
    return inner  # 切记不要加括号


def func(*args,**kwargs):
    print(f"这是{args}函数,李业还是不行")
    time.sleep(2) #模拟网络延时
    
func = wrapper(func)
func("alex","sur")

结果
这是('alex', 'sur')和{'a': 1, 'b': 2, 'c': 'cqk'}函数,李业还是不行
这是('alex', 'sur')函数,李业还是不行
2.000854015350342

语法糖--必须放在函数定义正上方 @装饰器的名

# 高级
import time
def wrapper(f):
    def inner(*args,**kwargs):
        "被装饰前"
        start_time = time.time()
        f(*args,**kwargs) # func("alex")
        print(time.time() - start_time)
        "被装饰后"
    return inner  # 切记不要加括号

@wrapper  # func = wrapper(func)
def func(*args,**kwargs):
    print(f"这是{args}函数,李业还是不行")
    time.sleep(2) #模拟网络延时
@wrapper  # foo = wrapper(foo)
def foo(*args,**kwargs):
    print(f"这是{args}函数,常鑫穿齐*小短裤")
    time.sleep(3) #模拟网络延时
# func = wrapper(func)
# foo = wrapper(foo)
func("alex","sur")
foo("alex","sur")

结果:
这是('alex', 'sur')函数,李业还是不行
2.001922130584717
这是('alex', 'sur')函数,常鑫穿齐*小短裤
3.000284433364868

import time
def wrapper(f):#f = func
    def inner(*args,**kwargs):
        "被装饰前"
        start_time = time.time()
        ret = f(*args,**kwargs) # func("alex")
        print(time.time() - start_time)
        "被装饰后"
        return ret
    return inner  # 切记不要加括号

@wrapper  # func = wrapper(func)
def func(*args,**kwargs):
    print(f"这是{args}函数,李业还是不行")
    time.sleep(2) #模拟网络延时
    return "alex"
print(func())
结果:
这是()函数,李业还是不行
2.000833511352539
alex

标准版装饰器:

def wrapper(f):
    def inner(*args,**kwargs):
        '''执行被装饰函数之前的操作'''
        ret = f(*args,**kwargs)
        '''执行被装饰函数之后的操作'''
        return ret
    return inner
@wrapper
def func(*args,**kwargs):
    pass
func("sss",a=1)
  1. 看代码写结果:

    def wrapper(f):
        def inner(*args,**kwargs):
            print(111)
            ret = f(*args,**kwargs)
            print(222)
            return ret
        return inner
    
    def func():
        print(333)
    
    print(444)
    func()
    print(555)
    
    444
    333
    555
    
  2. 编写装饰器,在每次执行被装饰函数之前打印一句’每次执行被装饰函数之前都得先经过这里’。

    def func(f):
        def foo():
            print('每次执行被装饰函数之前都得先经过这里')
            f()
        return  foo
    @func
    def fun():
        print("你好啊")
    fun()
  3. 为函数写一个装饰器,把函数的返回值 +100 然后再返回。

    @wrapper
    def func():
        return 7
    
    result = func()
    print(result)
    def wrapper(f):
        def foo():
            return f()+100
        return foo
    
    @wrapper
    def func():
        return 7
    
    result = func()
    print(result)
  4. 请实现一个装饰器,通过一次调用使被装饰的函数重复执行5次。

    def wrapepr(f):
        def foo():
            for i in range(5):
                f()
        return foo
    
    @wrapepr
    def f1():
        print("你好啊")
    f1()
  5. 请实现一个装饰器,每次调用函数时,将被装饰的函数名以及调用被装饰函数的时间节点写入文件中。

    可用代码:
    import time
    struct_time = time.localtime()
    print(time.strftime("%Y-%m-%d %H:%M:%S",struct_time)) # 获取当前时间节点
    
    def func():
        print(func.__name__)
    函数名通过: 函数名.__name__获取。
import time
def wrapper(f):
    def foo():
        with open("time","a",encoding="utf-8") as f1:
            struct_time = time.localtime()
            f1.write(time.strftime("%Y-%m-%d %H:%M:%S\t",struct_time))
            f1.write(f.__name__+"\n")
        f()
    return foo
@wrapper
def func():
    print("你好啊")
func()

转载于:https://www.cnblogs.com/ciquankun/p/11232270.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值