知行编程网知行编程网  2022-12-23 05:00 知行编程网 隐藏边栏  5 
文章评分 0 次,平均分 0.0
导语: 本文主要介绍了关于python装饰器如何实现的相关知识,希望可以帮到处于编程学习途中的小伙伴

python装饰器的实现方法

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")

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

知行编程网
知行编程网 关注:1    粉丝:1
这个人很懒,什么都没写
扫一扫二维码分享