测试开发进阶(四)

闭包

def func():
    print('----func----')

    def wrapper():
        print('----wrapper----')

    return wrapper

print(func())
"""
----func----
<function func.<locals>.wrapper at 0x103bb77b8>
"""
func()()
"""
----func----
----wrapper----
"""

满足闭包的条件

  • 函数中嵌套一个函数
  • 外层函数的返回值是内层函数的函数名
  • 内层嵌套函数对外部作用域有一个非全局变量的引用

闭包的作用

  • 实现数据锁定
# 数据锁定
def func2():
    num = 1000

    def wrapper():
        print(f'这里使用了num的值{num}')

    return wrapper

wrapper = func2()
num = 10000
wrapper() # 这里使用了num的值1000

装饰器

开放封闭原则:软件实体应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的

装饰器的作用:在不更改原功能函数内部代码,并且不改变调用方法的情况下为原函数添加新的功能。

@:语法糖

def decorator(num):
    def wrapper():
        print(num)

    return wrapper

decorator(1000)()
def decorator1(func):
    def wrapper():
        print(func)# 1⃣️
        func()

    return wrapper


def func():
    print('这是func')#2⃣️


wra = decorator1(func)
wra()
"""
<function func at 0x1142421e0>1⃣️
这是func2⃣️
"""

@decorator1 # 等价于func1 = decorator1(func1)
def func1():
    print('这是func')

func1()

一个作用域的错误

a = 100
def func():
    print(a)
    a = 999
func()
"""
Traceback (most recent call last):
  File "/Users/zhongxin/Desktop/py/zx/04/0812_2.py", line 14, in <module>
    func()
  File "/Users/zhongxin/Desktop/py/zx/04/0812_2.py", line 12, in func
    print(a)
UnboundLocalError: local variable 'a' referenced before assignment
"""

装饰器常见应用场景

  • 权限校验
  • 计算时间⌛️
  • 环境准备和恢复工作
  • web自动化用例失败截图

Chrome插件推荐-ChroPath

元素定位

web自动化用例失败截图

from selenium import webdriver

browser = webdriver.Chrome()
browser.get('https://www.baidu.com')


def decorator(func):
    def wrapper():
        try:
            func()
        except:
            browser.save_screenshot('eroor.png')
            raise

    return wrapper


@decorator
def test_search():
    browser.find_element_by_id('kw').send_keys('selenium')
    browser.find_element_by_id('su11').click()


test_search()

截图

带参数的装饰器

def decorator(func):
    print('1')

    def wrapper(*args, **kwargs):
        print('2')
        func(*args, **kwargs)

    return wrapper


@decorator
def add_num(a, b):
    print(f'sum={a + b}')


add_num(11, 22)
"""
1
2
sum=33
"""

类实现装饰器

__call__:魔术方法,在对象使用括号调用的时候会触发

class MyDecorator(object):
    def __init__(self, func):
        self.func = func #⚠️⚠️⚠️

    def __call__(self, *args, **kwargs):
        print('这是__call__方法')
        self.func(*args, **kwargs)

    def func(self):
        print('这是MyDecorator的func方法')


@MyDecorator  # add_num = MyDecorator(add_num)
def add_num(a, b):
    print(f'sun={a + b}')


add_num(1, 2)

装饰器装饰类

def dceorator(func):
    def wrapper(*args, **kwargs):
        print('111')
        obj = func(*args, **kwargs)
        print('222')
        return obj

    return wrapper

@dceorator  # Hero = dceorator(Hero)
class Hero:
    def func(self):
        print('这是Hero的func')

h = Hero()
print(h)
h.func()
"""
111
222
<__main__.Hero object at 0x1033a4390>
这是Hero的func
"""

原文发布于微信公众号 - 测试游记(zx94_11)

原文发表时间:2019-08-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券