我已经开始编写Python 3.x客户端应用程序了。服务器应用程序已经存在并且用C语言编写。服务器提供了一个C头文件,其中包含用于通过UDP发送和接收数据的两种结构的定义(我正在使用Python的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功能并使代码更简单,数据易于访问(I '而是只使用Python标准模块,没有外部软件)。实现这一目标最优雅的方法是什么?
答案 0 :(得分:1)
您可以编写一个具有成员函数的类,使用struct.pack
等将数据打包/解包到类属性中。
我建议调查Construct。但我认为它还没有被移植到Python 3.x.构造已经中断了一段时间,但最近被新开发人员接受了,所以也许它很快就会支持Python 3.x.
答案 1 :(得分:1)
试试这个 - 适用于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
答案 2 :(得分:1)