韩漫免费漫画在线观看方法,《好好疼爱里面》免费看,年轻漂亮的女士护士内衣,妈妈醉酒后把我当爸爸电视剧

文章 > Python高级 > python中的装饰器的使用实战

python中的装饰器的使用实战

头像

silencement

2019-07-09 15:18:182927浏览 · 0收藏 · 0评论

1、装饰器的理解

装饰器是将一个函数镶嵌在另一个函数中进行重复使用的目的,不改变其结构,增加函数的使用方式,但是不用写过多冗余的代码;

装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。

通常用到的功能:1.引入日志;2.函数执行时间统计;3.执行函数前预备处理;4.执行函数后清理功能;5.权限校验;6.缓存

2、实现原理与通用写法

咱们可以从一个简单的记录函数运行时间的简单装饰器,举一反三,推导出一个通用的装饰器写法

import time
 
def timer(func):
    '''
    记录方法运行时间的装饰器
    :param func: 方法
    :return:函数对象
    '''
    def deco(*args, **kwargs):
        startTime = time.time()
        f = func(*args, **kwargs)
        endTime = time.time()
        msecs = (endTime - startTime) * 1000
        print("time is %d ms" % msecs)
        return f # 如果 func 有返回值得话,需要在此return回去,否则,默认返回值为 None,一般默认都返回
 
    return deco
 
 
@timer
def test(parameter):
    print("test is running!")
    time.sleep(1)
    return "Returned value" # 该函数有返回值,所以需要在 装饰器中的 deco 方法中 写返回值
 
 
t = test('aa')
print(t)

这是一个很简单的通用的记录时间的装饰器,从而推导出一个通用的装饰器写法:

def func_name(func): # 自定义装饰器函数名
    def deco(*args, **kwargs): # 将所有参数原封不动的进行传递
        print("在这个分割线之上写函数运行前的操作")
#         -----------分割线-----------
        f = func(*args, **kwargs)
#         -----------分割线-----------
        print("在这个分割线之后,return之前,写函数运行后的操作")
        return f # 如果 func 有返回值得话,需要在此return回去,否则,默认返回值为 None,一般默认都返回
 
    return deco
 
 
@func_name
def test(parameter):  # 8
    print("test is running!")
    time.sleep(1)
    return "Returned value" # 该函数有返回值,所以需要在 装饰器中的 deco 方法中 写返回值
 
 
t = test('aa')
print(t)

ok 装饰器到此可以完事了,一般情况下都能满足需求了,网上看那么多原理,有点儿浪费时间,我偏向实操型,实在不喜欢啰嗦那么多,就是干。

当然在开发过程中, 我们可能会遇到一些特殊情况,比如参数问题

1、给装饰器函数代参数(通用)

2、将执行函数的参数拆分计算等(比如:1000w的数据,拆分成100份执行等)(定制)

那就按顺序来

1、写一个代参数的装饰器

def logging(level):
    def wrapper(func):
        def inner_wrapper(*args, **kwargs):
            print("[{level}]: enter function {func}()".format(level=level, func=func.__name__))
            return func(*args, **kwargs)
        return inner_wrapper
    return wrapper
 
@logging(level='INFO')
def say(something):
    print("say {}!".format(something))
 
# 如果没有使用@语法,等同于
# say = logging(level='INFO')(say)
 
@logging(level='DEBUG')
def do(something):
    print("do {}...".format(something))
 
if __name__ == '__main__':
    say('hello')
    do("my work")

发现:就是在上面的通用的模板上又套了一层!!!,然后拿到里面的参数即可! so easy!!!

2、写一个参数拆分的装饰器,这个就稍微有点定制型了,不能像上面的一样通用了,举个 栗子:

def func_name(func): # 自定义装饰器函数名
    def deco(*args, **kwargs): # 将所有参数原封不动的进行传递
        print(args[0])
        f_list = []
        for i in range(0,args[0],100000):
            print(i)
            f_list.append(func(i))
#         f_list # 这儿应该按照既定规则,继续对这个结果进行拼接,如果是写文件、入库等操作,可以不用return
        return f_list   # 这儿如果有返回值得话,应该是
    
    return deco
 
@func_name
def test(parameter):  # 8
    print("test is running!")
    time.sleep(1)
    return "Returned value" # 该函数有返回值,所以需要在 装饰器中的 deco 方法中 写返回值
 
 
t = test(1000000)
print(t)

可以看出来,这个的定制性稍微高点,不通用,但是我们实现了我们的需求,所以,我们最应该理解并学会的是怎么用!!!

可以看出来,这个的定制性稍微高点,不通用,但是我们实现了我们的需求,所以,我们最应该理解并学会的是怎么用!!!

下面在介绍一下基于类实现的装饰器,那问题来了,我是实战派,我并没有用类装饰器的需求,所以,当个大盗吧,以后用到了不至于瞎找了!!!

装饰器函数其实是这样一个接口约束,它必须接受一个callable对象作为参数,然后返回一个callable对象。在Python中一般callable对象都是函数,但也有例外。只要某个对象重载了__call__()方法,那么这个对象就是callable的。

class Test():
    def __call__(self):
        print 'call me!'
t = Test()
t()  # call me

像__call__这样前后都带下划线的方法在Python中被称为内置方法,有时候也被称为魔法方法。重载这些魔法方法一般会改变对象的内部行为。上面这个例子就让一个类对象拥有了被调用的行为。

回到装饰器上的概念上来,装饰器要求接受一个callable对象,并返回一个callable对象(不太严谨,详见后文)。

那么用类来实现也是也可以的。我们可以让类的构造函数__init__()接受一个函数,然后重载__call__()并返回一个函数,也可以达到装饰器函数的效果。

class logging(object):
    def __init__(self, func):
        self.func = func
 
    def __call__(self, *args, **kwargs):
        print "[DEBUG]: enter function {func}()".format(
            func=self.func.__name__)
        return self.func(*args, **kwargs)
@logging
def say(something):
    print "say {}!".format(something)

带参数的类装饰器

如果需要通过类形式实现带参数的装饰器,那么会比前面的例子稍微复杂一点。那么在构造函数里接受的就不是一个函数,而是传入的参数。通过类把这些参数保存起来。

然后在重载__call__方法是就需要接受一个函数并返回一个函数。

class logging(object):
    def __init__(self, level='INFO'):
        self.level = level
        
    def __call__(self, func): # 接受函数
        def wrapper(*args, **kwargs):
            print "[{level}]: enter function {func}()".format(
                level=self.level,
                func=func.__name__)
            func(*args, **kwargs)
        return wrapper  #返回函数
 
@logging(level='INFO')
def say(something):
    print "say {}!".format(something)
关注

关注公众号,随时随地在线学习

本教程部分素材来源于网络,版权问题联系站长!

跳舞机歌曲| 免费B站看大片真人电视剧| 四川少女B站免费入口 | 小泽玛利亚| 两人一起做AJ的视频教程| 教练车内含乳挺进她漫画| 免费B站看大片真人电视剧| 《从上司到妻子》动画结局| 灭火宝贝2户外版| 春闺艳妇(古言)作者:年富一年| 他的巨物撑开她的花缝的导演是谁 | 男生把困困放到女生坤坤视频高清| 少女配狗播放视频| 《酒店激战》动漫1-5集免费观.. 少女尖叫之夜1-4集免费 | BUBBLE| 二人生猴子全程免费下载| 赵局长含着小婷的双乳| 《黏糊糊的你》免费观看| 精品免费国产一区二区二区四区| 成品人和精品人的区别9点| 亚洲乱熟女-区二区三区山口珠理| 日韩A片| 女士穿紧身裸体开裆光滑皮裤| 《别告诉我丈夫》电影| 黑色蕾丝女装大长腿| 李丽珍电影经典免费观看| 8848高清电影电视剧免费看| 酒店实拍100部视频最新进展| 女生的全身照曝光| 《艳乳欲乱2》免费观看| 蜜桃5荷尔蒙| 女人高潮抖动多久能恢复正常 | 快拨出天我是你母亲歌词监控| 女教师免费观看全集电视剧| BOBO浏览器老司机模式改版特.| 《性房纵欲》在线观看| 7777777亚洲和欧洲尺码表| 孕妇| 美味的小瘦子3| 空姐4免费高清完整版观看| 抵达花心乖叫老公是第几集