紫玉葡萄藤

导航

python装饰器

python装饰器

​ 装饰器本质上是一个Python函数(该函数的参数是一个函数,返回值也是一个函数),它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。

装饰器用于性能测试

使用函数编写装饰器

import time
def log_time(func):
    def _log(*args, **kwargs):
        starttime = time.time()
        res = func(*args, **kwargs)
        print('use time: {}'.format(time.time() - starttime))
        return res
    return _log

@log_time
def my_func():
    time.sleep(2)

my_func()

使用类编写装饰器

import time
class LogTime:
    def __call__(self, func):
        def _log(*args, **kwargs):
            starttime = time.time()
            res = func(*args, **kwargs)
            print('use time: {}'.format(time.time() - starttime))
            return res
        return _log

@LogTime()
def my_func():
    time.sleep(2)

my_func()

装饰器用于权限校验

使用函数编写装饰器

account = {
    "is_authenticated":False,# 用户登录了就把这个改成True
    "username":"purple", # 假装这是DB里存的用户信息
    "password":"123456" # 假装这是DB里存的用户信息
}

def login(func):
    def _login(*args, **kwargs):
        if account["is_authenticated"] is False:
            user = input('user:')
            password = input('password:')
            if user == account["username"] and password == account["password"]:
                print("welcome %s" % user)
                account["is_authenticated"] = True
            else:
                print("wrong username or password!")

        if account["is_authenticated"]:
                func(*args, **kwargs)

    return _login

@login
def sichuan():
    print("sichuan region.")

sichuan()

如何给装饰器增加参数?

使用类装饰器比较方便实现装饰器参数

import time
class LogTimeParams:
    def __init__(self, use_int = False):
        self.use_int = use_int
    def __call__(self, func):
        def _log(*args, **kwargs):
            starttime = time.time()
            res = func(*args, **kwargs)
            if self.use_int:
                print('use time: {}'.format(int(time.time() - starttime)))
            else:
                print('use time: {}'.format(time.time() - starttime))
            return res
        return _log

@LogTimeParams(True)
def my_func():
    time.sleep(2)

my_func()

打印函数名及参数的装饰器

import functools

def log(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print('call %s():' % func.__name__)
        print('args = {}'.format(*args))
        return func(*args, **kwargs)

    return wrapper

@log
def test(p):
    print(test.__name__ + " param: " + p)

test("I'm a param")

posted on 2020-07-26 17:00  紫玉葡萄藤  阅读(38)  评论(0编辑  收藏  举报