ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Python装饰器

2021-08-04 14:01:38  阅读:121  来源: 互联网

标签:return name Python func time print 装饰 def


目录

1.装饰器

  • 开放封闭原则

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

2.装饰器初始

装饰器就是一个函数

范例

def inex():
    time.sleep(2)
    print("欢迎....")

def func(x):		
    def func2():
        start_time = time.time()
        x() #由于传入的实参是index 所以这里是index();下相当于闭包 x是自由变量
        end_time = time.time()
        print(end_time - start_time)
    return func2

index = func(inex)  #代码走到这里会执行 func(index);将index做为实参传给func(x)->func(index);执行完return func2(这个func2也就是里边嵌套的函数)
index()     #这个也就是执行func2那个函数
>>>
欢迎....
2.00072979927063

2.1 由上方演变的装饰器标准版初

#定义一个装饰器的函数
def func1(func_name):
    def func2():
        start_time = time.time()
        func_name()
        end_time = time.time()
        print(end_time - start_time)
    return func2
@func1          #装饰器中的语法糖;这里等用于 index = func1(index);注意此处@func1和下面的def index是结合的
def index():
    time.sleep(1)
    print("欢迎")
    return 666
index()

@func1          #每次需要调用装饰器的时候 都要在此函数头上加上一个@func1(语法糖)
def come():
    time.sleep(1)
    print('login')
come()

2.2 带有返回值的装饰器

#带有返回值的装饰器
def func2(x):
    def func3():
        start_time = time.time()
        ret = x()
        end_time = time.time()
        print(end_time - start_time)
        return ret
    return  func3
@func2                  #使用语法糖声明装饰器(与下边的func函数)
def func():
    time.sleep(0.5)
    print("欢迎登录博客...")
    return 666          #此返回值是func函数的返回值 ;重点是”func“这个函数是装饰器里边的 x()所调用的 所以要给x()赋一个值 并return
ret = func()
print(ret)
print(func())
>>>
欢迎登录博客...
0.5008265972137451
666
欢迎登录博客...
0.5003719329833984
666

2.3 带参数的装饰器

def func2(x):
    def func3(name):
        print(name)
        start_time = time.time()
        ret = x(name)
        end_time = time.time()
        print(end_time - start_time)
        return ret
    return  func3
# @func2                  #使用语法糖声明装饰器(与下边的func函数)
def func(name):
    time.sleep(0.5)
    print(f"欢迎登录{name}博客...")
    return 666          #此返回值是func函数的返回值 ;重点是”func“这个函数是装饰器里边的 x()所调用的 所以要给x()赋一个值 并return

ret = func2(func)       #执行这部会调用上方的 func2函数 func2的函数返回值是 func3 所以这时 ret 就等于 func3
ret('liu')             #执行到这 会调用上方的 fun3函数 并将'liu'传给func3(name)位置参数 再将name传给x(name->'liu')

#加上语法糖
def func2(x):
    def func3(name):
        print(name)
        start_time = time.time()
        ret = x(name)
        end_time = time.time()
        print(end_time - start_time)
        return ret
    return  func3
@func2                  #使用语法糖声明装饰器(与下边的func函数)
def func(name):
    time.sleep(0.5)
    print(f"欢迎登录{name}博客...")
    return 666          #此返回值是func函数的返回值 ;重点是”func“这个函数是装饰器里边的 x()所调用的 所以要给x()赋一个值 并return
func('liu')
>>>
liu
欢迎登录liu博客...
0.5000627040863037

2.4 万能参数的标准版的装饰器

def func2(x):
    def func3(*args,**kwargs):#函数的定义 函数的聚合 * args 

        start_time = time.time()
        ret = x(*args,**kwargs)
        #函数的执行 * 打散:x(*args) -->x(*(‘liu’,22)) --> x(‘liu’,22)
        end_time = time.time()
        print(end_time - start_time)
        return ret
    return  func3
@func2                  #使用语法糖声明装饰器(与下边的func函数)
def func(name,age,hobby='运动'):
    time.sleep(0.5)
    print(f"欢迎登录{name}{age}岁博客爱好{hobby}...")
    return 666          #此返回值是func函数的返回值 ;重点是”func“这个函数是装饰器里边的 x()所调用的 所以要给x()赋一个值 并return
func('liu',10,hobby='python')
# ret = func2(func)       #执行这部会调用上方的 func2函数 func2的函数返回值是 func3 所以这时 ret 就等于 func3
# ret('liu')             #执行到这 会调用上方的 fun3函数 并将'liu'传给func3(name)位置参数 再将name传给x(name->'liu')
@func2
def blog(name,age):
    print(f'欢迎使用{name},{age}岁的日志功能...')

blog('Liu',15)

def func2(x):
    def func3(*args,**kwargs):
        for i in args:
            print(i)
        for k, v in kwargs.items():
            print(k, v)
        start_time = time.time()
        ret = x(*args,**kwargs)
        end_time = time.time()
        print(end_time - start_time)
        return ret
    return  func3
@func2                  #使用语法糖声明装饰器(与下边的func函数)
def func(name,age,hobby='运动'):
    time.sleep(0.5)
    print(f"欢迎登录{name}{age}岁博客爱好{hobby}...")
    return 666          #此返回值是func函数的返回值 ;重点是”func“这个函数是装饰器里边的 x()所调用的 所以要给x()赋一个值 并return
func('liux',10,hobby='python')
# ret = func2(func)       #执行这部会调用上方的 func2函数 func2的函数返回值是 func3 所以这时 ret 就等于 func3
# ret('liu')             #执行到这 会调用上方的 fun3函数 并将'liux'传给func3(name)位置参数 再将name传给x(name->'liux')
@func2
def blog(name,age):
    print(f'欢迎使用{name},{age}岁的日志功能...')

blog('Liu',15)

2.5 最终版的装饰器

def wrapper(f):
    def inner(*args,**kwargs):
        ''' 添加额外的功能:执行被装饰函数之前的操作 '''
        ret = f(*args,**kwargs)
        ''' 添加额外的功能:执行被装饰函数之后的操作'''
        return ret
    return inner

3.装饰器的应用

实现基于用户登录成功以后才能执行 comment() darit() 函数

user_info = {}
def register():
    user = input('请输入注册的用户:')
    passwd = input('请输入注册的密码:')
    user_info[user] = passwd
def login():
    count = 1
    while count < 4:
        username = input('请输入您的用户名:')
        userpasswd = input('请输入您的密码:')
        if username not in user_info.keys():
            print('sorry,您的用户不存在需要注册~')
            register()
        elif username in user_info.keys() and userpasswd == user_info.get(username):
            print('登录成功')
            return 1

        else:
            print('sorry 输入有误')
            count += 1
dic = {'status':0}
def wrapper(f):
    def inner(*args,**kwargs):
        if dic.get('status') == 1:
            ret = f(*args, **kwargs)
        else:
            login_ret = login()
            if login_ret == 1:
                dic['status'] =1
                ret = f(*args, **kwargs)
    return inner


@wrapper
def comment():
    print('欢迎访问评论页面.')

comment()
@wrapper
def darit():
    print('欢迎访问日记页面')

darit()

4. 装饰器例子

def timmer(*args,**kwargs):
    c = args
    dct = kwargs
    def tim(func):

        def time(*args,**kwargs):
            print('start...')
            res = func(*args,**kwargs)
            print('end...')
            print(c,dct)
           # print(name)
            return res
        return time
    return tim



@timmer('liu',18,name='liu') #f1=f(f1)
def f1(x,y,z):
    print(f'from f1...{x} {y} {z}')
@timmer
def f2(x,y,z):
    print(f'from f1...{x} {y} {z}')
    return 123

f1(1,2,3)

标签:return,name,Python,func,time,print,装饰,def
来源: https://www.cnblogs.com/precipitation/p/15098563.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有