python装饰器详解

一、什么是装饰器

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

二、以下是一个时间模块插入日志的装饰器

import functools

import time

def add_logs(func):

'''

1.创建装饰器,创建add_log装饰器, 被装饰的函数打印日志信息;

2. 日志格式为: [字符串时间] 函数名: xxx, 运行时间:xxx, 运行返

    :paramfunc:

    :return:

'''

    def wrapper(*args,**kw):

start_time = time.time()

res = func(*args,**kw)

end_time = time.time()

print ('函数名:{0} 运行时间:{1}'.format(func.__name__ , (end_time - start_time)))

return res

return wrapper

@add_logs

def add(x,y):

time.sleep(1)

return x+y

a = add(1,20)

print(a)


从上面的例子中可以可以看出:装饰器就是一个闭包,闭包的定义:在一个内部函数中,对外部作用域的变量进行引用,(并且一般外部函数的返回值为内部函数),那么内部函数就被认为是闭包。

三、介绍一个用户权限模块的装饰器案例:

# Create an account

user_auth = [{'username':'lufei','password':'123456'}]

# # 初始登录状态信息

# current_dic = {'username': None, 'login': False}

# Initial login status information

login_dic = {'username':None, 'login':False}

# Create login function decorator

def auth_func(func):

def wrapper(*args,**kwargs):

if login_dic['username']and login_dic['login']:

res = func(*args, **kwargs)

return res

while True:

username =input('plase input username:')

password =input('plase input password:')

for user_dicin user_auth:

if username == user_dic['username']and password == user_dic['password']:

login_dic['username'] = username

login_dic['login'] =True

                    res = func(*args, **kwargs)

return res

else:

print('password is error')

return wrapper()

@auth_func

def index():

print('欢迎来到天猫购物商城')

@auth_func

def shoppingcar():

print('购物车:%s,%s,%s' % ('火锅底料', '三明治', '冰淇淋'))

index()

shoppingcar()


从上面的例子可以看出来我们用装饰器做了一个登录模块的验证功能的装饰器,验证用户是否登录成功,一个电商网站很多模块都要判断用户的的权限,只有用户登录成功,采用权限下单,支付,评价等等操作,我们不需要每一个模块都要验证用户的登录状态,只需要写一个判断登录权限的装饰器就完美解决了,大大的提高了代码的冗余和开发的效率。

四、介绍一个用户缓存模块的装饰器案例

缓存的应用场景:数据在需要频繁查询,且每次查询都需要大量计算或者等待时间之后才能返回结果的情况,使用缓存来提高查询速度,用内存空间换取查询、加载的时间。

那缓存应该采用什么数据结果呢?

1.便于查询的,且能快速获得数据的数据结构,每次查询的时候,只要输入一致,就应该得到同样的结果(顺序也一致,例如减法函数,参数顺序不一致,结果不一样)基于上面的分析,此数据结构应该是字典。

import time

import datetime

def cache(d={},cache_time=3):

def _cache(func):

def wrapper(*args,**kwargs):

if d.get(args)is None or datetime.datetime.now().timestamp()-d[args][1]>cache_time:

value = func(*args,**kwargs)

d[args] = (value,datetime.datetime.now().timestamp())

return value

else:

print('using cache')

print(d[args][0])

return d[args][0]

return wrapper

return _cache

@cache(cache_time=15)

def test_func(x,y):

print(x**y)

return x**y

test_func(1,2)

time.sleep(4)

test_func(1,2)

test_func(2,4)

test_func(2,4)



参考文献:https://blog.csdn.net/weixin_43936969/article/details/103823711

参考文献:https: // blog.csdn.net / maergaiyun / article / details /82724679

参考文献:https://blog.csdn.net/qq_32835305/article/details/86561995?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,012评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,628评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,653评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,485评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,574评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,590评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,596评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,340评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,794评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,102评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,276评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,940评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,583评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,201评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,441评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,173评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,136评论 2 352

推荐阅读更多精彩内容

  • 装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返...
    胡一巴阅读 411评论 0 0
  • 1. 什么是装饰器 知乎大佬如是说:内裤可以用来遮羞,但是到了冬天它没法为我们防风御寒,聪明的人们发明了长裤,有了...
    我只是我笔下的小丑阅读 281评论 0 1
  • 一、装饰器的基本使用 在不改变函数源代码的前提下,给函数添加新的功能,这时就需要用到“装饰器”。 0.开放封闭原则...
    NJingZYuan阅读 527评论 0 0
  • 在学习Python的过程中,我相信有很多人和我一样,对Python的装饰器一直觉得很困惑,我也是困惑了好久,并通过...
    愚灬墨阅读 458评论 1 1
  • 装饰器 创建装饰器, 要求如下:创建add_log装饰器, 被装饰的函数打印日志信息;日志格式为: [字符串时间]...
    ivan_cq阅读 363评论 0 0