• 技术文章 >常见问题 >Python常见问题

    python装饰器如何实现

    silencementsilencement2019-11-12 14:50:28原创2574

    1、装饰器的理解

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

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

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

    2、实现原理与通用写法

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

    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

    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)

    python学习网,免费的python学习网站,欢迎在线学习!

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

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    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、写一个代参数的装饰器

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

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

    专题推荐:装饰器
    上一篇:python中if和try的区别 下一篇:python如何用帮助函数

    相关文章推荐

    • Python黑魔法之property装饰器详解

    全部评论我要评论

    © 2021 Python学习网 苏ICP备2021003149号-1

  • 取消发布评论
  • 

    Python学习网