码迷,mamicode.com
首页 > 编程语言 > 详细

Python使用闭包自动生成函数

时间:2017-12-22 21:50:23      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:load   基础   express   并且   export   stat   field   top   tor   

背景

在构建测试用例集时,常常需要编写一些函数,这些函数接受基本相同的参数,仅有一个参数有所差异,并且处理模式也非常相同。可以使用Python闭包来定义模板函数,然后通过参数调节来自动化生产不同的函数。

示例

看如下代码:

def commonGenerate(startTime, endTime, field, values):
    reqs = []
    for val in values:
        requestId = str(startTime) + "_" + str(endTime) + "_" + val
        baseReq = json.loads(baseExportReqStr)
        baseReq['order_search_param']['start_time'] = startTime
        baseReq['order_search_param']['end_time'] = endTime
        baseReq['order_search_param'][field] = [val]
        baseReq['request_id'] = requestId
        reqs.append(json.dumps(baseReq))
    return reqs

def generateReqByState(startTime, endTime):
    states = ["TOPAY", "CONFIRM", "PAID", "SENT", "SUCCESS", "CLOSE"]
    return commonGenerate(startTime, endTime, 'order_state', states)

def generateReqByOrderType(startTime, endTime):
    orderTypes = ["NORMAL", "GROUP", "HOTEL"]
    return commonGenerate(startTime, endTime, 'order_type', orderTypes)

def generateReqByExpressType(startTime, endTime):
    expressTypes = ["EXPRESS", "SELF_FETCH", "LOCAL_DELIVERY"]
    return commonGenerate(startTime, endTime, 'express_type', expressTypes)

def generateReqByFeedback(startTime, endTime):
    feedbacks = ["SAFE_NEW", "SAFE_FINISHED"]
    return commonGenerate(startTime, endTime, 'feedback', feedbacks)

def getGenerateFuncs():
    gvars = globals()
    return [ gvars[var] for var in gvars if var.startswith('generateReq')  ]

caseGenerateFuncs = getGenerateFuncs()
print caseGenerateFuncs

这里已经抽离出通用函数 commonGenerate ,在此基础上定义了多个 generateReqByXXX ,这些函数的模式基本相同,无非是传一个字段名及值列表,然后生成一个不一样的函数。 那么,是否可以做成可配置化呢: 只要给定一个 map[字段名,值列表], 就能自动生成这些函数 ?

使用闭包可以达到这个目标。见如下代码所示:

def commonGenerator(startTime, endTime, field, values):
    def generateReqInner(startTime, endTime):
        reqs = []
        for val in values:
            requestId = str(startTime) + "_" + str(endTime) + "_" + val
            baseReq = json.loads(baseExportReqStr)
            baseReq['order_search_param']['start_time'] = startTime
            baseReq['order_search_param']['end_time'] = endTime
            baseReq['order_search_param'][field] = [val]
            baseReq['request_id'] = requestId
            reqs.append(json.dumps(baseReq))
        return reqs
    return generateReqInner

def generateGenerators(startTime, endTime, configs):
    gvars = globals()
    for (field, values) in configs.iteritems():
        gvars['generateReqBy' + field] = commonGenerator(startTime, endTime, field, values)

configs = {"order_state": ["TOPAY", "CONFIRM", "PAID", "SENT", "SUCCESS", "CLOSE"], \
           "order_type": ["NORMAL", "GROUP", "HOTEL"], \
           "express_type": ["EXPRESS", "SELF_FETCH", "LOCAL_DELIVERY"], \
           "feedback": ["SAFE_NEW", "SAFE_FINISHED"]
           }

def getGenerateFuncs():
    gvars = globals()
    return [ gvars[var] for var in gvars if var.startswith('generateReq')  ]

generateGenerators(startTime, endTime, configs)
caseGenerateFuncs = getGenerateFuncs()
print caseGenerateFuncs

这里函数 commonGenerator 对 commonGenerate 做了一点改动,不再直接返回值列表,而是根据不同的参数返回一个处理不同的函数,这个函数会返回值列表; 然后 generateGenerators 根据指定配置 configs, 调用commonGenerator 来批量生产generateReqByXXX函数。妙不妙,生产函数的函数 !

原理

按维基的解释: 闭包是引用了自由变量的函数。在例子中,闭包就是 generateReqInner , 引用了传入的自由变量 field, values, 从而在 commonGenerator 调用结束之后,generateReqInner 依然存在能够被访问,且功能效果等同于 generateReqInner(startTime, endTime, field, values) 。

小结

通过Python闭包自动化生成函数,使得代码表达能力更强大了。只要做一点配置,就能自动生成相应的函数。

Python使用闭包自动生成函数

标签:load   基础   express   并且   export   stat   field   top   tor   

原文地址:http://www.cnblogs.com/lovesqcc/p/8087510.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!