问题描述
我已经开始编写Python 3.x客户端应用程序.服务器应用程序已经存在并写在C中.服务器提供了一个C标头文件,其定义用于通过UDP发送和接收数据的两个结构(我正在使用Python's socket模块). 问题是C结构很大(每个元素约为200个).如果我使用python的struct模块打包/解开数据,则不太重要的解决方案将手动打包/解开200个元素,例如:
struct.pack('H...I', data1, ..., data200)
此外,我希望能够使用类似C的语法访问Python中的接收/发送元素.例如,如果我在C服务器端
send.data.pos = pos;
如果我可以在Python客户端访问pos变量,那将是不错的(最自然的):
pos = recv.data.pos
请注意,问题是不是如何从标题文件中自动编写python的结构,例如 this 线程(我在python中逐一编写一个结构字段没有问题),而是在Python中组织数据的最佳方法(例如,在课堂中,使用字典等)将使我能够利用Python功能并使代码更简单,并且易于访问的数据(我宁愿仅使用Python标准模块,而没有外部软件).实现这一目标的最优雅方法是什么?
推荐答案
尝试一下 - 在2.7和3.2上工作.
脚本:
import struct, collections class CStruct(object): def __init__(self, typename, format_defn, lead_char="!"): self.names = [] fmts = [lead_char] for line in format_defn.splitlines(): name, fmt = line.split() self.names.append(name) fmts.append(fmt) self.formatstr = ''.join(fmts) self.struct = struct.Struct(self.formatstr) self.named_tuple_class= collections.namedtuple(typename, self.names) def object_from_bytes(self, byte_str): atuple = self.struct.unpack(byte_str) return self.named_tuple_class._make(atuple) if __name__ == "__main__": # do this once pkt_def = """\ u1 B u2 H u4 I""" cs = CStruct("Packet1", pkt_def) # do this once per incoming packet o = cs.object_from_bytes(b"\xF1\x00\xF2\x00\x00\x00\xF4") print(o) print(o.u4)
输出:
Packet1(u1=241, u2=242, u4=244) 244
其他推荐答案
您可以编写具有成员函数的类,可以使用struct.pack等.
我建议您研究 struction .但是我认为它还没有移植到python 3.x.构造已经停滞了一段时间,但是最近被新开发人员接收,因此也许很快就可以支持Python 3.x.
其他推荐答案
您也许可以使用 dpkt 作为一种简单的访问方式数据包数据.看看在这里用于使用示例.对于一个简单的示例:
class Foo(dpkt.Packet): __hdr__ = (('type', 'B', 0), ('size', 'B', 0)) data = get_udp_message() foo = Foo(data) if foo.size != len(data): print "Bad size in header" if foo.type == 3: parse_payload(foo.data)