Python函数装饰器

Posted IamJet

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python函数装饰器相关的知识,希望对你有一定的参考价值。

装饰器的原则

1)不修改被修饰函数的源代码;

2)不修改被修饰函数的调用方式;

装饰器的知识点 = 高阶函数 + 函数嵌套 + 闭包

1. 只用高阶函数写装饰器--->有瑕疵

import time

def foo():
    print(this is foo)
    # return foo

def timer(func):
    starttime = time.time()
    func()
    stoptime = time.time()
    print(使用的时间是:%s %(stoptime - starttime))
    return func

foo = timer(foo)
foo()

#执行结果是:
# this is foo
# 使用的时间是:0.00013685226440429688
# this is foo            #多了一次执行结果

2. 闭包其实就是函数的嵌套

def First(name):
    print(FirstLayer:%s %name)
    def Second():
        name = bbb
        print(SecondLayer:%s %name)
        def Third():
            name = ccc
            print(ThirdLayer:%s %name)
        Third()
    Second()
First(aaa)

3. 函数闭包装饰器基本实现

# 实现阶段1:只需要在原来函数调用之前进行赋值操作。
import  time

def timer(func):   #func == test
    def good():
        starttime = time.time()
        func()
        stoptime = time.time()
        print(程序消耗的时间是:%s %(stoptime - starttime))
    return good

def test():
    print(这是test函数)

test = timer(test)      #此处函数运行的结果是return的good,可以看下一步证实。
print(timer(test))      #<function timer.<locals>.good at 0x10e3cb700>,因此需要下一步运行返回值函数good。
test()                  #test = good
# 实现阶段2:通过语法糖改进后,完全不需要动原来函数;
import time

def timer(func):   #func == test
    def good():
        starttime = time.time()
        func()
        stoptime = time.time()
        print(程序消耗的时间是:%s %(stoptime - starttime))
    return good

@timer  #@timer  相当于 test = timer(test)

def test():
    print(这是test函数)
test()
# 实现阶段3:如何打印出真正test的返回值
import time

def timer(func):   #func == test
    def good():
        starttime = time.time()
        res = func()            #就是在运行test()
        stoptime = time.time()
        print(程序消耗的时间是:%s %(stoptime - starttime))
        return res
    return good

@timer  #@timer  相当于 test = timer(test)

def test():
    print(这是test函数)
    return 这是test的返回值
ras = test()
print(ras)
# 阶段4装饰器适用于不同参数个数的函数
import time

def timer(func):   #func == test
    def good(*args,**kwargs):
        starttime = time.time()
        res = func(*args,**kwargs)            #就是在运行test()
        stoptime = time.time()
        print(程序消耗的时间是:%s %(stoptime - starttime))
        return res
    return good

@timer  #@timer  相当于 test = timer(test)

def test(name,age,gender):
    print(这是test函数,名字是%s,年龄是%s,性别是%s %(name,age,gender))
    return 这是test的返回值
ras = test(aaa,18,male)
print(ras)

@timer   #@timer  相当于 test1 = timer(test1)
def test1(name,age,gender,hight):
    print(这是test1函数,,名字是%s,年龄是%s,性别是%s,身高是%s %(name,age,gender,hight))
    return 这是test1的返回值
ras = test1(bbb,20,male,175)
print(ras)

# 如下为返回结果:
# 这是test函数,名字是aaa,年龄是18,性别是male
# 程序消耗的时间是:8.0108642578125e-05
# 这是test的返回值
# 这是test1函数,,名字是bbb,年龄是20,性别是male,身高是175
# 程序消耗的时间是:1.0013580322265625e-05
# 这是test1的返回值

4. 解压序列补充

# 使用解压序列取列表中的最开头和最结尾的值,可灵活使用。
>>> l = [1,2,3,4,5,6]
>>> a,*_,b = l
>>> l
[1, 2, 3, 4, 5, 6]
>>> a
1
>>> b
6
>>> a,*b,c = l
>>> a
1
>>> b
[2, 3, 4, 5]
>>> c
6
#快速交换两个变量的值
>>> f1,f2 = 1,2
>>> f1
1
>>> f2
2
>>> f1,f2 = f2,f1
>>> f1
2
>>> f2
1

5. 终极版装饰器-带参数验证功能的装饰器

user_list=[
    {name:alex,passwd:123},
    {name:linhaifeng,passwd:123},
    {name:wupeiqi,passwd:123},
    {name:yuanhao,passwd:123},
]
current_dic={username:None,login:False}

def auth(auth_type=filedb):
    def auth_func(func):
        def wrapper(*args,**kwargs):
            print(认证类型是,auth_type)
            if auth_type == filedb:
                if current_dic[username] and current_dic[login]:
                    res = func(*args, **kwargs)
                    return res
                username=input(用户名:).strip()
                passwd=input(密码:).strip()
                for user_dic in user_list:
                    if username == user_dic[name] and passwd == user_dic[passwd]:
                        current_dic[username]=username
                        current_dic[login]=True
                        res = func(*args, **kwargs)
                        return res
                else:
                    print(用户名或者密码错误)
            elif auth_type == ldap:
                print(鬼才特么会玩)
                res = func(*args, **kwargs)
                return res
            else:
                print(鬼才知道你用的什么认证方式)
                res = func(*args, **kwargs)
                return res

        return wrapper
    return auth_func

@auth(auth_type=filedb) #auth_func=auth(auth_type=‘filedb‘)-->@auth_func 附加了一个auth_type  --->index=auth_func(index)
def index():
    print(欢迎来到京东主页)

@auth(auth_type=ldap)
def home(name):
    print(欢迎回家%s %name)
#
@auth(auth_type=sssssss)
def shopping_car(name):
    print(%s的购物车里有[%s,%s,%s] %(name,奶茶,妹妹,娃娃))

# print(‘before-->‘,current_dic)
# index()
# print(‘after--->‘,current_dic)
# home(‘产品经理‘)
shopping_car(产品经理)

 

以上是关于Python函数装饰器的主要内容,如果未能解决你的问题,请参考以下文章

python 装饰器

[TimLinux] Python 装饰器

python装饰器

python函数装饰器

Python装饰器

python装饰器