• 根据python protobuf自动生成protobuf包收发接口


    利用protobuf进行串行化和反串行化处理,封装出来的rpc服务很好用。但是有个缺点,就是测试时,一些很简单的接口都要重新实现一次,程序体内就一些简单的赋值语句。写了个代码生成器,用来生成protobuf对应的请求函数和回应函数,请求函数根据req的内容,生成赋值函数体;回应函数只是负责把服务器返回的包进行打印。

    先用.proto文件生成protobuf的xxx_pb2.py文件,将其放入protobuf目录

    #!/usr/bin/env python
    #
    -*- coding:utf8 -*-

    import sys
    import protobuf #生成的protobuf python文件目录

    def dir_class(obj):
    """ dir_class(obj) -> list of string """
    names = dir(obj)
    names = [name for name in names if not name.startswith('_')]
    names = [name for name in names if not name.isupper()]
    request_class = [name for name in names if "Req" in name]
    response_class = [name for name in names if "Resp" in name]
    return request_class, response_class #返回接收包和发送包的对应类名称列表

    def dir_attr(obj):
    """ dir_attr(obj) -> list of string """
    names = dir(obj)
    names = [name for name in names if not name.startswith('_')]
    names = [name for name in names if name.islower()]
    return names #返回一个类的内部属性

    def gen_req(obj, class_name):
    text = []
    attrs = dir_attr(obj)
    line = gen_func_def(camercase_to_underscore(class_name), attrs)
    text.append(line)
    cp_statement = gen_cp(class_name, attrs)
    text.extend(cp_statement)
    line = "\tsingle_request(req)"
    text.append(line)
    return text #生成请求类的函数体

    def gen_func_def(func_name, arglist):
    line = "def " + func_name + "("
    if not arglist:
    line += "):"
    return line
    line += ", ".join(arglist) + "):"
    return line

    def gen_cp(class_name, attrs):
    text = []
    text.append("\treq = " + class_name + "()")
    for attr in attrs:
    line = "\treq." + attr + " = " + attr
    text.append(line)
    return text

    def camercase_to_underscore(var_name):
    result = []
    start = 0
    for i, char in enumerate(var_name):
    if char.isupper():
    result.append(var_name[start:i])
    start = i
    result.append(var_name[start:])
    underscore_name = "_".join([var.lower() for var in result])
    underscore_name = underscore_name[1:]
    return underscore_name #驼峰命名法到下划线分割的命名

    def underscore_to_camercase(var_name):
    result = var_name.split("_")
    result = [word.capitalize() for word in result]
    return "".join(result) #下划线分割的命名到驼峰法命名

    def main():
    with open(sys.argv[1]) as fh:
    lines = fh.readlines()
    for line in lines:
    line = line.strip()
    if line.startswith("protobuf"):
    #import package
    __import__(line, globals(), locals(), [], -1)
    #analysis class
    protobuf_package = eval(line)
    pb2_req, pb2_resp = dir_class(protobuf_package)
    #gen request function and resp printer
    req_funcs = []
    for req in pb2_req:
    req_func = gen_req(eval(line + "." + req + "()"), req)
    req_funcs.extend(req_func)
    req_funcs.append("")
    #write file
    filename = line[len("protobuf") + 1:]
    filename = filename[:-4]
    import_statement = "from " + line + "" + "import *"
    body = "\n".join(req_funcs)
    with open(filename+".py", "w") as f:
    print filename
    f.write("\n".join([import_statement, body]))

    if __name__ == '__main__':
    main()



  • 相关阅读:
    HDU 1878 欧拉回路(DFS)
    HDU 2181 哈密顿绕行世界问题(DFS)
    HDU 1181 变形课(DFS)
    HDU 1029 Ignatius and the Princess IV(map应用)
    HDU 1242 Rescue(BFS)
    HDU 1027 Ignatius and the Princess II(STL)
    将项目部署到本地IIS时出现的奇怪问题
    [转]30个你必须记住的css选择器
    打开一个从网络上下载的chm文件时出现“已取消到该网页的导航”
    [转]使用Modernizr 检测HTML5和CSS3浏览器支持功能
  • 原文地址:https://www.cnblogs.com/Lifehacker/p/code_generator_for_protobuf_py.html
Copyright © 2020-2023  润新知