无参装饰器

装饰器的概念

就是给被装饰对象添加新功能的工具,作用是在不改变原有被装饰对象代码和调用方式的情况下,为装饰对象添加新的功能。

装饰器分为有参装饰器和无参装饰器,都是基于函数嵌套、闭包、函数对象实现的

装饰器的简易版本

#先写一个被装饰的函数
import time

def index():
    print('index')
    time.sleep(3)

现在我们想为这个函数增加一个统计其运行时间的功能

start_time=time.time()
index()
end_time=time.time()
print('当前函数运行时间为%s' %(end_time-start_time))

 现在虽然原函数调用方式和源代码都没有被改变,但是如果多处使用的话,就会造成代码重复和冗余,这个时候就需要利用函数把这个功能整合起来

def inner():
    start_time = time.time()
    index()
    end_time = time.time()
    print('当前函数运行时间为%s' % (end_time - start_time))
inner()

但是index这个地方的函数名就写死了,如果别的函数也需要添加这个功能就需要修改,所以我们把这个地方的index换成参数形式 

def inner(func):
    start_time = time.time()
    func()
    end_time = time.time()
    print('当前函数运行时间为%s' % (end_time - start_time))
inner(index)

这里index的调用方式就发生了改变,所以这不是装饰器了。我们需要利用闭包函数的第二种传值方式。

def outer(func):
    # func=index
    def inner():
        start_time = time.time()
        func()
        end_time = time.time()
        print('当前函数运行时间为%s' % (end_time - start_time))
    return inner#记得把inner返回给outer
# res=outer(index)
# res()
index=outer(index)#注意此时的index已经不是原来函数的index了,而是inner的内存地址
index()#inner()

 这时的原函数的代码没有被修改,调用方式也没有被改变。这就是一个简易版的无参装饰器。

 

装饰器进阶版本

解决参数问题

但是如果涉及到被装饰函数的参数,就会报错

import time

def index(a,b):
    print('index')
    time.sleep(3)


def outer(func):
    # func=index
    def inner():#由于没有接收的参数所以会报错
        start_time = time.time()
        func()
        end_time = time.time()
        print('当前函数运行时间为%s' % (end_time - start_time))
    return inner#记得把inner返回给outer
# res=outer(index)
# res()
index=outer(index)#注意此时的index已经不是原来函数的index了,而是inner的内存地址
index(1,2)#inner()

 这个时候就需要用到可变长参数

def outer(func):
    # func=index
    def inner(*args,**kwargs):#参数接收变成元组和字典形式
        start_time = time.time()
        func(*args,**kwargs)#元组和字典形式的参数打散成位置参数和关键参数
        end_time = time.time()
        print('当前函数运行时间为%s' % (end_time - start_time))
    return inner#记得把inner返回给outer
# res=outer(index)
# res()
index=outer(index)#注意此时的index已经不是原来函数的index了,而是inner的内存地址
index(1,2)#inner()

 

解决返回值问题

但是inner依旧伪装的不够像,没有和被装饰函数相同的返回值,这个时候我们就给他赋值

def outer(func):
    # func=index
    def inner(*args,**kwargs):#参数接收变成元组和字典形式
        start_time = time.time()
        res=func(*args,**kwargs)#相当于index的return返回值给res
        end_time = time.time()
        print('当前函数运行时间为%s' % (end_time - start_time))
        return res#这里inner返回的值就和index也就是被装饰对象是同一个返回值了
    return inner#记得把inner返回给outer
# res=outer(index)
# res()
index=outer(index)#注意此时的index已经不是原来函数的index了,而是inner的内存地址
index(1,2)#inner()

 

装饰器练习题

写一个登录功能的装饰器,要求在验证成功后,后续函数登录就不需要验证了

def index():
    print('from index')
def home():
    print('from home')
def abcd():
    print('from index1')
is_login={'is_login':False}
def outer(func):
    def inner(*args,**kwargs):

        if is_login.get('is_login'):
            res=func()
            return res
        username = input('username:>>>').strip()
        password = input('password:>>>').strip()
        if username == 'kk' and password == '123':
            # 执行函数
            print('登录成功')
            res=func(*args,**kwargs)
            is_login['is_login'] = True
            return res
        else:
            print('用户名或者密码错误')

    return inner
index=outer(index)
index()
home=outer(home)
home()
abcd=outer(abcd)
abcd()

装饰器的固定模板

  def index(func):
    print('index')  
  def outer():  
    def inner(*args,**kwargs):
        print('被装饰对象前的代码')
        res=func(*args,**kwargs)
        print('被装饰对象后的代码')
        return res
    return inner
  index=outer(index)
  index()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值