Python教程

Python装饰器

本文主要是介绍Python装饰器,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录
  • 1.装饰器
  • 2.装饰器初始
    • 2.1 由上方演变的装饰器标准版初
    • 2.2 带有返回值的装饰器
    • 2.3 带参数的装饰器
    • 2.4 万能参数的标准版的装饰器
    • 2.5 最终版的装饰器
  • 3.装饰器的应用
  • 4. 装饰器例子

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)
这篇关于Python装饰器的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!