软件测试UI自动化天花板电子书---免费分享

64 阅读4分钟

​编辑​ ​​编辑​ ​​编辑​

篇幅太长,截取三页目录,需要的看我简介加V获取

  • 装饰器

**“”” **在这之前小北想说为什么要使用装饰器:因为优雅 ”””

    1. 装饰器概念

装饰器是 Python 中****用于修改函数或类的语法结构的工具(元类也可以修改类,不过一般推荐使用装饰器来修改类)** **。它是一种以函数作为输入参数,并返回一个函数作为输出的函数,可以在不改变原有函数代码的情况下,给函数增加一些功能或者改变函数的行为。

装饰器的使用方式是在函数定义的上方使用 @decorator_name 的形式将装饰器应用到函数上,这样定义的函数在被调用时会先执行装饰器函数,再执行原始函数。常见的装饰器有类装饰器、函数装饰器、属性装饰器等。

装饰器本身需要接受一个被装饰的对象作为参数,该参数通常为函数、方法、类等对象。

装饰器需要返回一个对象,该对象可以是 经过处理的原参数对象、一个包装且类似原参数的对象;或者返回一个不相干内容(通常不建议使用)

1.2、装饰器类型介绍【前三是最常用的】

1.2.1 最简单的装饰器

在调用函数前后都输出一行文字

def my_decorator(func):

    def wrapper():

        print("Before the function is called.")

        func()

        print("After the function is called.")

    return wrapper

@my_decorator

def say_hello():

print("Hello!")

say_hello()

解释:

  1. 当我们调用被装饰器修饰的函数的时候,首先会把say_hello的函数传入my_decorator的func参数中,然后再去执行内部的wrapper函数(在这个函数内部就会操作很多东西,比如增删改等操作),最后返回wrapper函数。
  2. 实际上我们调用的say_hello函数没有被执行,那这里为什么执行了呢?是因为wrapper函数里面又调用了一次它,如果不调用,那么say_hello函数就是一个装饰,但是通常情况下都会调用一次来达到我们的一些特殊目的。

1.2.2.用于修改对象和函数的装饰器

编辑

****1.2.3.用于模拟对象的装饰器--函数装饰器【 重点中的重点

编辑

Python中被装饰后的函数,函数名等函数属性会发生改变(相当于另一个函数了),所以,Python的functools包中提供了一个叫wraps的装饰器来解决该问题。它能使其保留原有函数的结构。

**1、 **不加@wraps()的装饰器:

import time

class MyLog(object):

    def call(self, func):

        def my_log(*args, **kwargs):

            """这里是my_log的docstring"""

            start = time.time()

            res = func(*args, **kwargs)

            end = time.time()

            print('|传入的原函数的运行时长:{:.4f}'.format(end - start))

            return res

        return my_log

@MyLog()

def is_test():

    """这里是is_test的docstring"""

print("一个测试方法")

is_test()

print("name: ", is_test.name)

print("doc:  ", is_test.doc)

运行结果:

编辑

看运行结果,会发现,被装饰器装饰后的函数,name和docstring都发生了变化,因为相当于调用my_log函数。

**2、 **加了@wraps()的装饰器

import time 

from functools import wraps

class MyLog(object):

    def call(self, func):

        @wraps(func)

        def my_log(*args, **kwargs):

            """这里是my_log的docstring"""

            start = time.time()

            res = func(*args, **kwargs)

            end = time.time()

            print('|传入的原函数的运行时长:{:.4f}'.format(end - start))

            return res

        return my_log

@MyLog()

def is_test():

    """这里是is_test的docstring"""

    print("一个测试方法")

is_test()

print("name: ", is_test.name)

print("doc:  ", is_test.doc)

运行结果 :

编辑

看运行结果,会发现,装饰器加了@wraps后,被装饰器装饰后的函数,还是保持原有的状态

**1、 ****装饰器的作用: 在不改变原有功能代码的基础上, ******添加额外的功能。

**2、 ****@wraps(func)的作用: 不改变使用装饰器原有函数的结构(如name, doc) **

1.2.4.用于模拟对象的装饰器--类方法装饰器

编辑

1.2.5.用于模拟对象的装饰器--类装饰器