美文网首页
python设计模式之装饰器decorator

python设计模式之装饰器decorator

作者: Judy警官 | 来源:发表于2019-10-24 16:38 被阅读0次

最近学习了装饰器,就想着如何把它用到自己自动化框架中去。发现每个脚本都需要设置浏览器模式为三星galaxy s5,属于重复性代码。就想到用装饰器来优化下代码,使得代码都可读性和可复制性更强。
以下是装饰器模块的代码:

#coding=utf-8
from selenium import webdriver
options=webdriver.ChromeOptions()
def set_phone_model(phone_model):
    def __deco(func):
        def _deco(self,*arg, **kw):
            mobile_emulation = {'deviceName': phone_model}
            options.add_experimental_option("mobileEmulation", mobile_emulation)
            func(self,*arg, **kw)
            return options
        return _deco
    return __deco

以下是使用装饰器的代码,test_Search_By_Name是测试脚本(此处省略了整个类的其他无关部分):

from selenium import webdriver
from util.decorator.PhoneModelDecorator import set_phone_model,options
@set_phone_model('Galaxy S5')
    def test_Search_By_Name(self):
          browser = webdriver.Chrome(chrome_options=options)
          browser.get("https://jdread.jd.com/h5/m/")

使用装饰器之前的代码,test_Search_By_Name是测试脚本(此处省略了整个类的其他无关部分):

from util.decorator.PhoneModelDecorator import set_phone_model,options
from selenium import webdriver
mobile_emulation = {'deviceName': 'Galaxy S5'}
 options = webdriver.ChromeOptions()
 options.add_experimental_option("mobileEmulation", mobile_emulation)
 browser = webdriver.Chrome(chrome_options=options)

装饰器的用法分析:

def deco(s):
    def __deco(func):
        def _deco(*arg,**kw):
            print ("before %s called." %func.__name__,s)
            print(func(*arg,**kw))
            print ("  after %s called." %func.__name__,s)
            # 不需要返回func,实际上应返回原函数的返回值
        return _deco
    return __deco
#闭包:_deco+func

@deco("hello")
def myfunc(a,b):
    print (" myfunc() called.")
    return a+b

myfunc(1,2)
myfunc(3,4)

总结:

装饰器使用了一个“闭包”的概念
闭包就是:函数返回一个内置函数(_deco)+传入的参数(func函数)

装饰器的规则:
规则1:
函数func上面定义了@deco,那么等价于 执行了func = deco(func)
规则2:
装饰函数deco,必须返回一个闭包(一个内置函数+func)

分析调用过程:

首先myfunc上面放了@deco("hello"),相当于执行了myfunc = deco(myfunc),返回了闭包:__deco(myfunc)+“hello”
然后,__deco(myfunc)返回了一个闭包_deco+myfunc
此时,myfunc已经不再是原来的myfunc而是带有装饰的myfunc,执行了_deco里的逻辑:前置操作( print ("before %s called." %func.name,s)
)+myfunc+后置操作(print (" after %s called." %func.name,s))

相关文章

网友评论

      本文标题:python设计模式之装饰器decorator

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