美文网首页
python 装饰器

python 装饰器

作者: SlashMan | 来源:发表于2018-10-16 23:12 被阅读0次

    一、理论

    1、装饰器定义

    本质上是函数(装饰其他函数),就是为其他函数添加附加功能。

    2、原则

    1、不能修改被装饰的函数的源代码

    2、不能修改被装饰的函数的调用方式

    3、实现装饰器知识储备:

    1.函数即“变量”

    2.高阶函数(a.把一个函数名当做实参传给另外一个函数(不修改被装饰函数源代码的情况下为其添加功能);b.返回值中包含函数名(不修改函数的调用方法))

    3.嵌套函数

    而高阶函数 + 嵌套函数 = 装饰器

    二、实现

    先说一下高阶函数,高阶函数的定义上面已经说了(a、把一个函数名当做实参传给另外一个函数;b.返回值中包含函数名)。只要实现了a条件就是高阶函数,b为可选条件。

    现在有一个最原始的函数func

    def func():

        time.sleep(3)

        print("in the func")

    现在要写一个高阶函数,要把func以一个参数的形式传入这个高阶函数中,并给func函数添加一个计算func函数运行时间的功能

    def test1(func):

          start_time = time.time()

          func()

          stop_time = time.time()

          print("the func run time is %s" % (stop_time - start_time))

    此时如果要实现功能的话只需要调用test1就行了,这样的话不符合装饰器的原则。

    那如何在调用func的同时也实现想要进行装饰的功能(计算func的运行时间)那。

    我们用嵌套函数试试

    def foo():

          print("in the foo")

          def func():

          time.sleep(3)

          print("in the func")

          start_time = time.time()

          func()

          stop_time = time.time()

          print("the run time is %s" % (stop_time - start_time))

    此时也是只要调用foo函数就行了。和用高阶函数一样。那我如何在调用func 的同时也能实现附加功能那。此时不防用高阶函数 + 嵌套函数来试试。我先用一个高阶函数来接受func作为参数,然后在高阶函数中嵌套一个函数来添加附加功能。并将嵌套的函数作为返回值传出来。

    def test5(func):

          def test4():

                start_time = time.time()

                func()

                stop_time = time.time()

                print("the run time is %s" % (stop_time - start_time))

          return test4

    此时如果应该怎样去调用这些函数那,我们需要定义一个变量来接受test4(添加附件功能的函数),然后定义这个函数就可以了。

    func = test5(func)

    func()

    此时的func实际上就是test5中嵌套的test4。运行程序,此时的打印结果为

    in the test3

    the run time is 3.0007569789886475

    基本上实现了装饰器的功能,但是也改变了原函数的调用方法。在python中有一个装饰器的修饰方法。就是在原函数的上一行加上“@装饰器函数”。这样就可以直接调用原函数,而且实现附加功能了。例如上面我们是用test5来作为func的装饰器函数的,此时如果在func的定义函数的上一行加上“@test5”,此时只需要调用func函数也能实现附加功能

    @test5

    def func():

    time.sleep(3)

        print("in the func")

    现在调用直接调用func函数也能实现附加功能了。而这里的“@test5”的功能就相当于“func = test5(func)”。到此装饰器就实现了。但是如果func函数也是有参数传入的那应该怎么办那。上面说过了其实被装饰器装饰过的函数,在调用时,实际上是调用的装饰器函数中嵌套的函数,那么我们在嵌套函数的定义中也写上参数不就解决了嘛。是的。但是参数的个数是不确定的,如何在不确定参数的情况下,接受全部参数,如下所示

    def test5(func):

          def test4(*args, **kwargs):

                start_time = time.time()

                func(*args, **kwargs)

                stop_time = time.time()

                print("the run time is %s" % (stop_time - start_time))

          return test4

    这样装饰器就完全实现了。

    现在有两个函数,表示两种不同的登录方式,一个是本地登录,另外一个是需要远程连接服务器认证的。那么如何同时给这两个函数,区别去添加功能,并且将第一个函数的返回值也传出去。首先需要给装饰器传入一个参数来区别两种登录方式。

    #第一个登录函数(有返回值)

    @auth(auth_type="local")

    def login(*args, **kwargs):

          print("welcome to home page")

          return "from home"

    第二个登录函数

    @auth(auth_type="ldap")

    def loginTwo(*args, **kwargs):

          print("welcome to loginTwo page")

    此时装饰器1、多嵌套一层来接受auth_type参数,2、如下如所示红框内为返回原函数的返回值。

    图1

    代码下载:https://github.com/zhangyunf/python-.git

    相关文章

      网友评论

          本文标题:python 装饰器

          本文链接:https://www.haomeiwen.com/subject/vnskzftx.html