Python中装饰器是什么?Python中装饰器的介绍


本文摘自php中文网,作者不言,侵删。

本篇文章给大家带来的内容是关于Python中装饰器是什么?Python中装饰器的介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

一、什么是装饰器

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

装饰器通过不修改核心代码而增强核心代码部分的功能。例如在函数前插入日志、权限校验、事务处理等场景。
而且可以抽离出大量与函数功能无关的雷同代码并重用。

二、早期实现:不是装饰器的装饰器

  • Python中函数也可以看做是一个对象,可以赋值给变量,并通过变量调用该函数。

例如:

1

2

3

4

5

6

def foo():

   print("2017-06-08")

f = foo    # 将函数赋值给变量,f为函数对象

f()

# 返回结果:

2017-06-08

三、语法糖@ 实现简单装饰器

假设现在要增强foo()的功能,例如,在函数调用前打印日志。但是又不希望修改foo()函数的定义。在这种代码运行期间动态增加功能的方式,称之为“装饰器”。
如下:

1

2

3

4

5

6

7

8

9

10

11

def testfunc(func):

    print('testfunc')

    def wrapper():

        print("%s %s() called" %(time.ctime(),func.__name__))

        return func()

    return wrapper

@testfunc

def foo():

    print('foo1()')

 

foo()  # 相当于执行testfunc(foo) ->wrapper(foo) -> foo()

执行结果:

1

2

3

testfunc

Wed Sep 12 15:01:13 2018 foo() called

foo1()

说明:执行foo()前,先执行testfunc(foo),再执行wrapper(),返回时调用foo()本身。

四、接收特定类型参数的装饰器

  • 装饰器可以接收参数,当调用装饰器返回的函数时,也就调用了包裹函数,把参数传入包裹函数,它将参数传递给被装饰的函数。

如下:

1

2

3

4

5

6

7

8

9

10

def testfunc_with_args(func):

    def wrapper_argus(arg1, arg2):

        print("I got args! Look:", arg1, arg2)

        func(arg1, arg2)

    return wrapper_argus

@testfunc_with_args

def full_name(first_name, last_name):  # 带参数,将参数传给被装饰的函数

    print("My name is", first_name, last_name)

 

full_name("Peter", "Venkman")  # 调用

执行结果:

1

2

I got args! Look: Peter Venkman

My name is Peter Venkman

五、带不定参数的装饰器

当有多个函数需要调用装饰器,但是函数的参数各不同时,该如何实现呢?总不能一个函数对应一个装饰器吧。这时候就可以用带不定参数的装饰器进行实现。
如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

def log(func):

    def wrapper(*args,**kwargs):        # 可接受各种参数

        print('call %s():'% func.__name__)

        return func(*args,**kwargs)     # 返回一个函数

    return wrapper                      # 装饰器返回一个函数,进入到wrapper()

 

@log      # @log放到now()的定义处,相当于执行语句:now = log(now)

def now_1(a,b):

    print('now()1:a+b = ',a+b)

@log

def now_2(a,b,c):

    print('now_2():a+b+c = ',a+b+c)

 

now_1(1,2)

now_2(1,2,3)

运行一下哦~

六、多个装饰器

当一个函数想要加入多项功能时,可以考虑使用多层装饰器,就是要注意一下装饰器的执行顺序。
举个栗子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

# 注意代码的执行顺序

def deco_1(func):

    print('------111111------')

    def wrapper(*args,**kwargs):    # 包裹函数,参数与原函数的参数一致

        print('start: this is deco_1.')

        func(*args,**kwargs)

        print('end: deco_1.')

    return wrapper  # 返回值是一个包裹函数

def deco_2(func):

    print('------222222------')

    def wrapper(*args,**kwargs):

        print('start: this is deco_2.')

        func(*args,**kwargs)

        print('end: deco_2.')

    return wrapper

 

@deco_1

@deco_2

def now_1(a,b):

    print('now()1:a+b = ',a+b)

 

now_1(1,2)

运行结果:

1

2

3

4

5

6

7

8

# 结果,注意执行顺序:

------222222------

------111111------

start: this is deco_1.

start: this is deco_2.

now()1:a+b =  3

end: deco_2.

end: deco_1.

七、装饰器本身带参数

除了给被装饰的函数带参数,装饰器本身也可以带参数。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

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

 

@logging(level='DEBUG')

def do(something):

    print("do {}...".format(something))

 

say('hello')

do("my work")

执行结果:

1

2

3

4

5

# 执行结果:

[INFO]: enter function say()

say hello!

[DEBUG]: enter function do()

do my work...

相关推荐:

python中的装饰器详解

Python中的各种装饰器详解

以上就是Python中装饰器是什么?Python中装饰器的介绍的详细内容,更多文章请关注木庄网络博客!!

相关阅读 >>

用cmd写Python怎么换行

Python怎么下载视频

hash()是Python内置的吗

Python函数之bin()函数详解

Python判断变量的类型吗

Python进阶看什么书

使用Python进行手机号和数字的随机生成方法

Python操作mysql代码总结

Python如何将数据导出excel的技巧分享

Python导入模块的关键字是什么

更多相关阅读请进入《Python》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...