Python 装饰器

吃可爱长大的小学妹 提交于 2020-03-18 04:38:05

Python装饰器

有这样一个函数,代码如下:

1
2
3
4
5
6
7
from functools import reduce
 
def sum():
    total = reduce(lambda x,y: x+y, range(100000))
    print (total)
 
sum()

现在我们需要计算该函数执行所花的时间,代码如下

1
2
3
4
5
6
7
8
9
10
11
import time
from functools import reduce
 
def sum():
    start_time = time.time()
    total = reduce(lambda x,y: x+y, range(10000))
    end_time = time.time()
    print (total)
    print ("time cost %fs" %(end_time - start_time))
 
sum()

如果有几十个不同的函数需要计算函数执行所花的时候,每个都加上这几条语句的话,麻烦而且浪费时间,这里,我们就可以用到装饰器了,装饰器的使用在要使用的函数上面加上@以及装饰器的函数名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import time
from functools import reduce
 
def time_cost(func):
    def inner():
        start_time = time.time()
        func()
        end_time = time.time()
        print ("time cost %fs" %(end_time - start_time))
    return inner
 
@time_cost
def sum():
    total = reduce(lambda x,y: x+y, range(10000))
    print (total)
 
sum()

此时sum函数将作为参数传递给time_cost函数,然后通过return语句执行inner语句中的内容,最后如果inner语句中有返回值,则将返回值重新赋值给sum函数

装饰器的功能是: 

  1. 自动执行装饰器的函数并且将其下面的函数名当作参数进行传递

  2. 将装饰器函数中的返回值重新赋值给其下面的函数

python内部也内置了一些装饰器,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Person:
 
    def __init__(self, name):
        self._name = name
         
    @staticmethod
    def say(name):
        print("say")
 
    @classmethod
    def eat(cls):
        print ("eat")
 
    @property
    def name(self):
        return self._name

装饰器下的函数也可以将里面的参数传递进来,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import time
from functools import reduce
 
def time_cost(func):
    def inner(arg):
        start_time = time.time()
        ret = func(arg)
        end_time = time.time()
        print ("time cost %fs" %(end_time - start_time))
        return ret
    return inner
  
@time_cost
def sum(n):
    total = reduce(lambda x,y: x+y, range(n))
    print (total)
  
sum(100000)

如果需要传递任意参数,可以这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import time
from functools import reduce
 
def time_cost(func):
    def inner(*args, **kwargs):
        start_time = time.time()
        ret = func(*args, **kwargs)
        end_time = time.time()
        print ("time cost %fs" %(end_time - start_time))
        return ret
    return inner
 
@time_cost
def sum(n):
    total = reduce(lambda x,y: x+y, range(n))
    print (total)
 
sum(100000)

有时候根据需要也可以使用多层装饰器来简化操作,例如有些系统在进行操作的时候首先要保证用户处于登录状态,有的操作在这基础之上还需要对权限进行检测,因此这里可以用到双层装饰器,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def check_login(func):
    def inner(*args, **kwargs):
        if user_data["is_authed"]:
            ret = func(*args, **kwargs)
            return ret
        else:
            print ("请登录")
            login()
    return inner
 
def check_role(func):
    def inner(*args, **kwargs):
        if user_data["user_type"] == 1:
            ret = func(*args, **kwargs)
            return func
        else:
            print ("您没有权限")
    return inner
 
@check_login
@check_role
def del_user():
    user = input("请输入您要删除的用户: ").strip()
    if user not in user_dict.keys():
        print ("该用户不存在")
    else:
         del user_dict[user]
         print ("用户 %s 删除成功" %user)

代码的执行顺序为: check_login()-->check_role-->del_user

 



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!